eyeling 1.16.3 → 1.16.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/package.json +2 -3
- package/arctifacts/README.md +0 -59
- package/arctifacts/ackermann.html +0 -678
- package/arctifacts/auroracare.html +0 -1297
- package/arctifacts/bike-trip.html +0 -752
- package/arctifacts/binomial-theorem.html +0 -631
- package/arctifacts/bmi.html +0 -511
- package/arctifacts/building-performance.html +0 -750
- package/arctifacts/clinical-care.html +0 -726
- package/arctifacts/collatz.html +0 -403
- package/arctifacts/complex.html +0 -321
- package/arctifacts/control-system.html +0 -482
- package/arctifacts/delfour.html +0 -849
- package/arctifacts/earthquake-epicenter.html +0 -982
- package/arctifacts/eco-route.html +0 -662
- package/arctifacts/euclid-infinitude.html +0 -564
- package/arctifacts/euler-identity.html +0 -667
- package/arctifacts/exoplanet-transit.html +0 -1000
- package/arctifacts/faltings-theorem.html +0 -1046
- package/arctifacts/fibonacci.html +0 -299
- package/arctifacts/fundamental-theorem-arithmetic.html +0 -398
- package/arctifacts/godel-numbering.html +0 -743
- package/arctifacts/gps-bike.html +0 -759
- package/arctifacts/gps-clinical-bench.html +0 -792
- package/arctifacts/graph-french.html +0 -449
- package/arctifacts/grass-molecular.html +0 -592
- package/arctifacts/group-theory.html +0 -740
- package/arctifacts/health-info.html +0 -833
- package/arctifacts/kaprekar-constant.html +0 -576
- package/arctifacts/lee.html +0 -805
- package/arctifacts/linked-lists.html +0 -502
- package/arctifacts/lldm.html +0 -612
- package/arctifacts/matrix-multiplication.html +0 -502
- package/arctifacts/matrix.html +0 -651
- package/arctifacts/newton-raphson.html +0 -944
- package/arctifacts/peano-factorial.html +0 -456
- package/arctifacts/pi.html +0 -363
- package/arctifacts/polynomial.html +0 -646
- package/arctifacts/prime.html +0 -366
- package/arctifacts/pythagorean-theorem.html +0 -468
- package/arctifacts/rest-path.html +0 -469
- package/arctifacts/roots-of-unity.html +0 -363
- package/arctifacts/turing.html +0 -409
- package/arctifacts/wind-turbines.html +0 -726
package/arctifacts/prime.html
DELETED
|
@@ -1,366 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<title>Primes</title>
|
|
7
|
-
<style>
|
|
8
|
-
:root {
|
|
9
|
-
--bg: #ffffff;
|
|
10
|
-
--ink: #111827;
|
|
11
|
-
--muted: #6b7280;
|
|
12
|
-
--panel: #f8fafc;
|
|
13
|
-
--border: #e5e7eb;
|
|
14
|
-
--accent: #0ea5e9;
|
|
15
|
-
--good: #16a34a;
|
|
16
|
-
--cyan: #06b6d4;
|
|
17
|
-
--indigo: #6366f1;
|
|
18
|
-
--warn: #dc2626;
|
|
19
|
-
--mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', monospace;
|
|
20
|
-
--ui:
|
|
21
|
-
system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', 'Apple Color Emoji',
|
|
22
|
-
'Segoe UI Emoji';
|
|
23
|
-
}
|
|
24
|
-
html,
|
|
25
|
-
body {
|
|
26
|
-
height: 100%;
|
|
27
|
-
}
|
|
28
|
-
body {
|
|
29
|
-
margin: 0;
|
|
30
|
-
background: var(--bg);
|
|
31
|
-
color: var(--ink);
|
|
32
|
-
font: 15px/1.55 var(--ui);
|
|
33
|
-
}
|
|
34
|
-
.wrap {
|
|
35
|
-
max-width: 980px;
|
|
36
|
-
margin: 28px auto;
|
|
37
|
-
padding: 0 14px;
|
|
38
|
-
}
|
|
39
|
-
header {
|
|
40
|
-
display: flex;
|
|
41
|
-
align-items: center;
|
|
42
|
-
justify-content: space-between;
|
|
43
|
-
margin-bottom: 14px;
|
|
44
|
-
}
|
|
45
|
-
h1 {
|
|
46
|
-
font-size: 20px;
|
|
47
|
-
margin: 0;
|
|
48
|
-
letter-spacing: 0.2px;
|
|
49
|
-
}
|
|
50
|
-
.pill {
|
|
51
|
-
display: inline-flex;
|
|
52
|
-
align-items: center;
|
|
53
|
-
gap: 8px;
|
|
54
|
-
padding: 6px 10px;
|
|
55
|
-
border: 1px solid var(--border);
|
|
56
|
-
border-radius: 999px;
|
|
57
|
-
color: var(--muted);
|
|
58
|
-
background: #fff;
|
|
59
|
-
}
|
|
60
|
-
.card {
|
|
61
|
-
width: 100%;
|
|
62
|
-
background: var(--panel);
|
|
63
|
-
border: 1px solid var(--border);
|
|
64
|
-
border-radius: 14px;
|
|
65
|
-
overflow: hidden;
|
|
66
|
-
margin-bottom: 14px;
|
|
67
|
-
}
|
|
68
|
-
.head {
|
|
69
|
-
display: flex;
|
|
70
|
-
align-items: center;
|
|
71
|
-
justify-content: space-between;
|
|
72
|
-
padding: 10px 12px;
|
|
73
|
-
border-bottom: 1px solid var(--border);
|
|
74
|
-
}
|
|
75
|
-
.head h2 {
|
|
76
|
-
font-size: 13px;
|
|
77
|
-
text-transform: uppercase;
|
|
78
|
-
letter-spacing: 0.08em;
|
|
79
|
-
color: var(--muted);
|
|
80
|
-
margin: 0;
|
|
81
|
-
}
|
|
82
|
-
.body {
|
|
83
|
-
padding: 12px;
|
|
84
|
-
}
|
|
85
|
-
pre {
|
|
86
|
-
white-space: pre-wrap;
|
|
87
|
-
background: #fff;
|
|
88
|
-
border: 1px solid var(--border);
|
|
89
|
-
border-radius: 10px;
|
|
90
|
-
padding: 12px;
|
|
91
|
-
overflow: auto;
|
|
92
|
-
font-family: var(--mono);
|
|
93
|
-
font-size: 13px;
|
|
94
|
-
margin: 0;
|
|
95
|
-
}
|
|
96
|
-
input[type='number'] {
|
|
97
|
-
width: 120px;
|
|
98
|
-
padding: 8px 10px;
|
|
99
|
-
border: 1px solid var(--border);
|
|
100
|
-
border-radius: 10px;
|
|
101
|
-
font: 14px var(--ui);
|
|
102
|
-
background: #fff;
|
|
103
|
-
}
|
|
104
|
-
button {
|
|
105
|
-
all: unset;
|
|
106
|
-
background: #fff;
|
|
107
|
-
border: 1px solid var(--border);
|
|
108
|
-
padding: 9px 13px;
|
|
109
|
-
border-radius: 10px;
|
|
110
|
-
cursor: pointer;
|
|
111
|
-
}
|
|
112
|
-
button:hover {
|
|
113
|
-
border-color: #cbd5e1;
|
|
114
|
-
}
|
|
115
|
-
.btns {
|
|
116
|
-
display: flex;
|
|
117
|
-
gap: 8px;
|
|
118
|
-
flex-wrap: wrap;
|
|
119
|
-
}
|
|
120
|
-
.muted {
|
|
121
|
-
color: var(--muted);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/* ARC boxes with thick colored left borders */
|
|
125
|
-
.arcbox {
|
|
126
|
-
background: #fff;
|
|
127
|
-
border: 1px solid var(--border);
|
|
128
|
-
border-radius: 12px;
|
|
129
|
-
padding: 10px;
|
|
130
|
-
margin: 10px 0;
|
|
131
|
-
}
|
|
132
|
-
.arcbox.answer {
|
|
133
|
-
border-left: 10px solid var(--good);
|
|
134
|
-
}
|
|
135
|
-
.arcbox.reason {
|
|
136
|
-
border-left: 10px solid var(--cyan);
|
|
137
|
-
}
|
|
138
|
-
.arcbox.check {
|
|
139
|
-
border-left: 10px solid var(--indigo);
|
|
140
|
-
}
|
|
141
|
-
.arclabel {
|
|
142
|
-
font-size: 11px;
|
|
143
|
-
text-transform: uppercase;
|
|
144
|
-
letter-spacing: 0.08em;
|
|
145
|
-
color: var(--muted);
|
|
146
|
-
margin-bottom: 6px;
|
|
147
|
-
}
|
|
148
|
-
</style>
|
|
149
|
-
</head>
|
|
150
|
-
<body>
|
|
151
|
-
<div class="wrap">
|
|
152
|
-
<header>
|
|
153
|
-
<h1>Primes</h1>
|
|
154
|
-
<div class="pill" id="status">Ready</div>
|
|
155
|
-
</header>
|
|
156
|
-
|
|
157
|
-
<div class="card">
|
|
158
|
-
<div class="body">
|
|
159
|
-
<p>
|
|
160
|
-
<strong>What this is?</strong> A self‑contained, browser‑only demo that lists primes up to a limit using a
|
|
161
|
-
Sieve of Eratosthenes and explains one proof of primality by trial division. The ARC section reports
|
|
162
|
-
<em>Answer • Reason • Check</em>.
|
|
163
|
-
</p>
|
|
164
|
-
</div>
|
|
165
|
-
</div>
|
|
166
|
-
|
|
167
|
-
<div class="card">
|
|
168
|
-
<div class="head"><h2>Settings</h2></div>
|
|
169
|
-
<div class="body" style="display: flex; gap: 10px; align-items: center; flex-wrap: wrap">
|
|
170
|
-
<label>Max n: <input id="limit" type="number" min="2" value="100" /></label>
|
|
171
|
-
<div class="btns">
|
|
172
|
-
<button onclick="run()">▶ Run</button>
|
|
173
|
-
<button onclick="copyARC()">Copy ARC</button>
|
|
174
|
-
<button onclick="downloadTxt()">⬇ Export .txt</button>
|
|
175
|
-
</div>
|
|
176
|
-
</div>
|
|
177
|
-
</div>
|
|
178
|
-
|
|
179
|
-
<div class="card">
|
|
180
|
-
<div class="head">
|
|
181
|
-
<h2>ARC Output</h2>
|
|
182
|
-
<div class="muted">Cards with left borders</div>
|
|
183
|
-
</div>
|
|
184
|
-
<div class="body">
|
|
185
|
-
<div class="arcbox answer">
|
|
186
|
-
<div class="arclabel">Answer</div>
|
|
187
|
-
<pre id="ans">(no run yet)</pre>
|
|
188
|
-
</div>
|
|
189
|
-
<div class="arcbox reason">
|
|
190
|
-
<div class="arclabel">Reason why</div>
|
|
191
|
-
<pre id="why">(no run yet)</pre>
|
|
192
|
-
</div>
|
|
193
|
-
<div class="arcbox check">
|
|
194
|
-
<div class="arclabel">Check (harness)</div>
|
|
195
|
-
<pre id="chk">(no run yet)</pre>
|
|
196
|
-
</div>
|
|
197
|
-
</div>
|
|
198
|
-
</div>
|
|
199
|
-
</div>
|
|
200
|
-
|
|
201
|
-
<script>
|
|
202
|
-
// ====== Number helpers ======
|
|
203
|
-
function sieve(n) {
|
|
204
|
-
const isPrime = new Uint8Array(n + 1);
|
|
205
|
-
isPrime.fill(1, 2); // assume 0/1 false, 2..n true
|
|
206
|
-
const lim = Math.floor(Math.sqrt(n));
|
|
207
|
-
for (let p = 2; p <= lim; p++) {
|
|
208
|
-
if (isPrime[p]) {
|
|
209
|
-
for (let k = p * p; k <= n; k += p) isPrime[k] = 0;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
const ps = [];
|
|
213
|
-
for (let i = 2; i <= n; i++) if (isPrime[i]) ps.push(i);
|
|
214
|
-
return ps;
|
|
215
|
-
}
|
|
216
|
-
function isPrimeTrial(n) {
|
|
217
|
-
if (n < 2) return false;
|
|
218
|
-
if (n % 2 === 0) return n === 2;
|
|
219
|
-
if (n % 3 === 0) return n === 3;
|
|
220
|
-
const lim = Math.floor(Math.sqrt(n));
|
|
221
|
-
for (let f = 5; f <= lim; f += 6) {
|
|
222
|
-
if (n % f === 0 || n % (f + 2) === 0) return false;
|
|
223
|
-
}
|
|
224
|
-
return true;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// ====== ARC ======
|
|
228
|
-
function setText(id, s) {
|
|
229
|
-
const el = document.getElementById(id);
|
|
230
|
-
if (el) el.textContent = s;
|
|
231
|
-
}
|
|
232
|
-
function status(msg, warn = false) {
|
|
233
|
-
const el = document.getElementById('status');
|
|
234
|
-
if (!el) return;
|
|
235
|
-
el.textContent = msg;
|
|
236
|
-
el.classList.toggle('warn', !!warn);
|
|
237
|
-
}
|
|
238
|
-
function fmtArr(a, wrapAt = 16) {
|
|
239
|
-
const parts = [];
|
|
240
|
-
let line = [];
|
|
241
|
-
for (const x of a) {
|
|
242
|
-
line.push(String(x).padStart(2, ' '));
|
|
243
|
-
if (line.length === wrapAt) {
|
|
244
|
-
parts.push(line.join(' '));
|
|
245
|
-
line = [];
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
if (line.length) parts.push(line.join(' '));
|
|
249
|
-
return parts.join('\n'); // placeholder, will be replaced
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// ====== fixed newline helper to avoid "\n" showing in output ======
|
|
253
|
-
const NL = '\n'.replace('\\n', '\n'); // ensures a single JS newline escape
|
|
254
|
-
|
|
255
|
-
function fmtArrFixed(a, wrapAt = 16) {
|
|
256
|
-
const parts = [];
|
|
257
|
-
let line = [];
|
|
258
|
-
for (const x of a) {
|
|
259
|
-
line.push(String(x).padStart(2, ' '));
|
|
260
|
-
if (line.length === wrapAt) {
|
|
261
|
-
parts.push(line.join(' '));
|
|
262
|
-
line = [];
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
if (line.length) parts.push(line.join(' '));
|
|
266
|
-
return parts.join(NL);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// Replacing functions to output real newlines
|
|
270
|
-
function proofTrace(n) {
|
|
271
|
-
if (n < 2) return `n = ${n} < 2 → not prime`;
|
|
272
|
-
const tests = [];
|
|
273
|
-
if (n % 2 === 0) {
|
|
274
|
-
tests.push('try 2 → divides');
|
|
275
|
-
return tests.join(NL);
|
|
276
|
-
}
|
|
277
|
-
if (n % 3 === 0) {
|
|
278
|
-
tests.push('try 3 → divides');
|
|
279
|
-
return tests.join(NL);
|
|
280
|
-
}
|
|
281
|
-
tests.push('try 2 → no');
|
|
282
|
-
tests.push('try 3 → no');
|
|
283
|
-
const lim = Math.floor(Math.sqrt(n));
|
|
284
|
-
for (let f = 5; f <= lim; f += 6) {
|
|
285
|
-
tests.push(`try ${f} → ${n % f === 0 ? 'divides' : 'no'}`);
|
|
286
|
-
if (n % f === 0) return tests.join(NL);
|
|
287
|
-
tests.push(`try ${f + 2} → ${n % (f + 2) === 0 ? 'divides' : 'no'}`);
|
|
288
|
-
if (n % (f + 2) === 0) return tests.join(NL);
|
|
289
|
-
}
|
|
290
|
-
tests.push(`no divisors ≤ √${n} = ${lim}`);
|
|
291
|
-
return tests.join(NL);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
function run() {
|
|
295
|
-
const N = Math.max(2, Math.floor(Number(document.getElementById('limit').value) || 100));
|
|
296
|
-
const primes = sieve(N);
|
|
297
|
-
// Answer
|
|
298
|
-
let A = ''.replaceAll('\\n', '\n');
|
|
299
|
-
A += `All primes ≤ ${N} (count = ${primes.length}):\n`.replaceAll('\\n', '\n');
|
|
300
|
-
A += fmtArrFixed(primes) + '\n'.replaceAll('\\n', '\n');
|
|
301
|
-
setText('ans', A);
|
|
302
|
-
|
|
303
|
-
// Reason
|
|
304
|
-
let R = ''.replaceAll('\\n', '\n');
|
|
305
|
-
R += 'We generate primes by the Sieve of Eratosthenes and justify primality of one example by\n'.replaceAll(
|
|
306
|
-
'\\n',
|
|
307
|
-
'\n',
|
|
308
|
-
);
|
|
309
|
-
R += 'trial division up to √ n, using 6k±1 candidates after checking 2 and 3.\n\n'.replaceAll('\\n', '\n');
|
|
310
|
-
// Pick a demo number close to N (prefer prime), trace trial division proof
|
|
311
|
-
let demo = N;
|
|
312
|
-
while (demo >= 2 && !isPrimeTrial(demo)) demo--;
|
|
313
|
-
if (demo < 2) demo = 97;
|
|
314
|
-
R += `Demo: show ${demo} is prime\n`.replaceAll('\\n', '\n');
|
|
315
|
-
R += proofTrace(demo);
|
|
316
|
-
setText('why', R);
|
|
317
|
-
|
|
318
|
-
// Check
|
|
319
|
-
let C = ''.replaceAll('\\n', '\n');
|
|
320
|
-
// A) Sieve set equals trial-division filter
|
|
321
|
-
const tv = [];
|
|
322
|
-
for (let i = 2; i <= N; i++) if (isPrimeTrial(i)) tv.push(i);
|
|
323
|
-
const same = JSON.stringify(primes) === JSON.stringify(tv);
|
|
324
|
-
C += `sieve == trial-division up to ${N}? ${same}\n`.replaceAll('\\n', '\n');
|
|
325
|
-
// B) 6k±1 property for primes > 3
|
|
326
|
-
const kprop = primes.filter((p) => p > 3).every((p) => (p - 1) % 6 === 0 || (p + 1) % 6 === 0);
|
|
327
|
-
C += `all p>3 satisfy p ∈ {6k±1}? ${kprop}\n`.replaceAll('\\n', '\n');
|
|
328
|
-
// C) sanity: first few primes and last prime ≤ N
|
|
329
|
-
const firstFewOK = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29].every((v, i) => primes[i] === v || i >= primes.length);
|
|
330
|
-
const lastOK = primes.length ? primes[primes.length - 1] === tv[tv.length - 1] : true;
|
|
331
|
-
C += `first few OK? ${firstFewOK} ; last OK? ${lastOK}`;
|
|
332
|
-
setText('chk', C);
|
|
333
|
-
|
|
334
|
-
status('Done');
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
function copyARC() {
|
|
338
|
-
const txt = [
|
|
339
|
-
document.getElementById('ans').textContent,
|
|
340
|
-
document.getElementById('why').textContent,
|
|
341
|
-
document.getElementById('chk').textContent,
|
|
342
|
-
].join('\n\n'.replaceAll('\\n', '\n'));
|
|
343
|
-
navigator.clipboard?.writeText(txt).catch(() => {});
|
|
344
|
-
}
|
|
345
|
-
function downloadTxt() {
|
|
346
|
-
const blob = new Blob(
|
|
347
|
-
[
|
|
348
|
-
document.getElementById('ans').textContent,
|
|
349
|
-
'\n\n'.replaceAll('\\n', '\n'),
|
|
350
|
-
document.getElementById('why').textContent,
|
|
351
|
-
'\n\n'.replaceAll('\\n', '\n'),
|
|
352
|
-
document.getElementById('chk').textContent,
|
|
353
|
-
],
|
|
354
|
-
{ type: 'text/plain' },
|
|
355
|
-
);
|
|
356
|
-
const a = document.createElement('a');
|
|
357
|
-
a.href = URL.createObjectURL(blob);
|
|
358
|
-
a.download = 'primes_output.txt';
|
|
359
|
-
a.click();
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
// auto-run
|
|
363
|
-
window.addEventListener('DOMContentLoaded', run);
|
|
364
|
-
</script>
|
|
365
|
-
</body>
|
|
366
|
-
</html>
|