eyeling 1.16.2 → 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.
Files changed (51) hide show
  1. package/HANDBOOK.md +4 -0
  2. package/README.md +0 -1
  3. package/examples/ershov-mixed-computation.n3 +106 -0
  4. package/examples/output/ershov-mixed-computation.n3 +15 -0
  5. package/eyeling.js +510 -263
  6. package/lib/cli.js +22 -12
  7. package/lib/engine.js +488 -251
  8. package/package.json +2 -3
  9. package/arctifacts/README.md +0 -59
  10. package/arctifacts/ackermann.html +0 -678
  11. package/arctifacts/auroracare.html +0 -1297
  12. package/arctifacts/bike-trip.html +0 -752
  13. package/arctifacts/binomial-theorem.html +0 -631
  14. package/arctifacts/bmi.html +0 -511
  15. package/arctifacts/building-performance.html +0 -750
  16. package/arctifacts/clinical-care.html +0 -726
  17. package/arctifacts/collatz.html +0 -403
  18. package/arctifacts/complex.html +0 -321
  19. package/arctifacts/control-system.html +0 -482
  20. package/arctifacts/delfour.html +0 -849
  21. package/arctifacts/earthquake-epicenter.html +0 -982
  22. package/arctifacts/eco-route.html +0 -662
  23. package/arctifacts/euclid-infinitude.html +0 -564
  24. package/arctifacts/euler-identity.html +0 -667
  25. package/arctifacts/exoplanet-transit.html +0 -1000
  26. package/arctifacts/faltings-theorem.html +0 -1046
  27. package/arctifacts/fibonacci.html +0 -299
  28. package/arctifacts/fundamental-theorem-arithmetic.html +0 -398
  29. package/arctifacts/godel-numbering.html +0 -743
  30. package/arctifacts/gps-bike.html +0 -759
  31. package/arctifacts/gps-clinical-bench.html +0 -792
  32. package/arctifacts/graph-french.html +0 -449
  33. package/arctifacts/grass-molecular.html +0 -592
  34. package/arctifacts/group-theory.html +0 -740
  35. package/arctifacts/health-info.html +0 -833
  36. package/arctifacts/kaprekar-constant.html +0 -576
  37. package/arctifacts/lee.html +0 -805
  38. package/arctifacts/linked-lists.html +0 -502
  39. package/arctifacts/lldm.html +0 -612
  40. package/arctifacts/matrix-multiplication.html +0 -502
  41. package/arctifacts/matrix.html +0 -651
  42. package/arctifacts/newton-raphson.html +0 -944
  43. package/arctifacts/peano-factorial.html +0 -456
  44. package/arctifacts/pi.html +0 -363
  45. package/arctifacts/polynomial.html +0 -646
  46. package/arctifacts/prime.html +0 -366
  47. package/arctifacts/pythagorean-theorem.html +0 -468
  48. package/arctifacts/rest-path.html +0 -469
  49. package/arctifacts/roots-of-unity.html +0 -363
  50. package/arctifacts/turing.html +0 -409
  51. package/arctifacts/wind-turbines.html +0 -726
@@ -1,403 +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>Collatz (3n+1)</title>
7
- <style>
8
- :root {
9
- --fg: #101014;
10
- --bg: #ffffff;
11
- --muted: #666;
12
- --accent: #2563eb;
13
- --chip: #eef2ff;
14
- }
15
- @media (prefers-color-scheme: dark) {
16
- :root {
17
- --fg: #eaeaf0;
18
- --bg: #0b0b10;
19
- --muted: #a0a0b0;
20
- --accent: #60a5fa;
21
- --chip: #0e1a32;
22
- }
23
- }
24
- html,
25
- body {
26
- margin: 0;
27
- padding: 0;
28
- background: var(--bg);
29
- color: var(--fg);
30
- font:
31
- 15px/1.6 ui-sans-serif,
32
- system-ui,
33
- -apple-system,
34
- Segoe UI,
35
- Roboto,
36
- Helvetica,
37
- Arial;
38
- }
39
- main {
40
- max-width: 1100px;
41
- margin: 0 auto;
42
- padding: 28px 16px 80px;
43
- }
44
- h1 {
45
- font-size: clamp(1.6rem, 2.6vw + 1rem, 2.2rem);
46
- margin: 0 0 6px;
47
- }
48
- header p {
49
- margin: 0;
50
- color: var(--muted);
51
- }
52
- section {
53
- margin: 18px 0 22px;
54
- padding: 14px 14px 16px;
55
- border: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
56
- border-radius: 14px;
57
- background: color-mix(in srgb, var(--accent) 4%, transparent);
58
- }
59
- section h2 {
60
- margin: 0 0 8px;
61
- font-size: 1.15rem;
62
- }
63
- .grid {
64
- display: grid;
65
- grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
66
- gap: 10px;
67
- }
68
- .chip {
69
- display: inline-block;
70
- padding: 2px 8px;
71
- border-radius: 999px;
72
- background: var(--chip);
73
- font-weight: 600;
74
- }
75
- .muted {
76
- color: var(--muted);
77
- }
78
- .row {
79
- display: flex;
80
- gap: 12px;
81
- align-items: center;
82
- flex-wrap: wrap;
83
- }
84
- .btn {
85
- appearance: none;
86
- border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
87
- background: color-mix(in srgb, var(--accent) 8%, transparent);
88
- color: var(--fg);
89
- border-radius: 10px;
90
- padding: 8px 12px;
91
- font-weight: 700;
92
- cursor: pointer;
93
- }
94
- .btn:disabled {
95
- opacity: 0.6;
96
- cursor: not-allowed;
97
- }
98
- .mono {
99
- font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace;
100
- }
101
- .tbl {
102
- width: 100%;
103
- border-collapse: collapse;
104
- }
105
- .tbl th,
106
- .tbl td {
107
- padding: 6px 8px;
108
- border-bottom: 1px dashed color-mix(in srgb, var(--fg) 18%, transparent);
109
- vertical-align: top;
110
- }
111
- .tbl th {
112
- text-align: left;
113
- }
114
- .ok {
115
- color: #16a34a;
116
- }
117
- .bad {
118
- color: #dc2626;
119
- }
120
- .small {
121
- font-size: 0.92em;
122
- }
123
- code {
124
- background: color-mix(in srgb, var(--accent) 10%, transparent);
125
- padding: 0.1rem 0.35rem;
126
- border-radius: 0.35rem;
127
- }
128
- input[type='number'],
129
- input[type='text'] {
130
- padding: 8px 10px;
131
- border-radius: 10px;
132
- border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
133
- min-width: 160px;
134
- }
135
- .nowrap {
136
- white-space: nowrap;
137
- }
138
- </style>
139
- </head>
140
- <body>
141
- <main>
142
- <header class="row">
143
- <div>
144
- <h1>Collatz (3n+1)</h1>
145
- </div>
146
- <div style="margin-left: auto" class="row">
147
- <label for="nInput" class="muted small">Try n:</label>
148
- <input id="nInput" type="text" value="27" inputmode="numeric" pattern="[0-9]*" />
149
- <button id="runBtn" class="btn">Compute</button>
150
- </div>
151
- </header>
152
-
153
- <section>
154
- <h2>What this is?</h2>
155
- <p>
156
- A single‑file explainer for the <em>Collatz</em> process a.k.a. the “3n+1 problem”. For a positive integer n,
157
- iterate: if n is even, divide by 2; if n is odd, set n ← 3n+1. This page computes trajectories, shows the
158
- <strong>Answer</strong> (stopping time, total stopping time, and peak), the
159
- <strong>Reason why</strong> (definitions and identities), and a <strong>Check</strong> harness that verifies
160
- basic properties (e.g., powers‑of‑two chains and termination for a range), all locally in JavaScript.
161
- </p>
162
- <p class="small muted">
163
- Note: The Collatz conjecture (that all n reach 1) is open; here we only check finite ranges.
164
- </p>
165
- </section>
166
-
167
- <section id="answer">
168
- <h2>Answer</h2>
169
- <div id="answer-body"></div>
170
- </section>
171
-
172
- <section id="reason">
173
- <h2>Reason why</h2>
174
- <div class="mono small">
175
- <p>Transition:</p>
176
- <p class="nowrap">T(n) = { n/2 &nbsp; if n is even; &nbsp; 3n+1 &nbsp; if n is odd }.</p>
177
- <p>
178
- For a start value n<sub>0</sub> = n, define the trajectory n<sub>0</sub>, n<sub>1</sub>, … with n<sub
179
- >k+1</sub
180
- >
181
- = T(n<sub>k</sub>).
182
- </p>
183
- <ul>
184
- <li><strong>Total stopping time</strong> σ∞(n): least k ≥ 0 with n<sub>k</sub> = 1 (if it exists).</li>
185
- <li><strong>Stopping time</strong> σ(n): least k ≥ 0 with n<sub>k</sub> &lt; n.</li>
186
- <li><strong>Peak</strong>: max value over the trajectory until 1 (inclusive).</li>
187
- </ul>
188
- <p>
189
- For powers of two, the sequence halves straight to 1, so σ∞(2<sup>k</sup>) = k and the peak is
190
- 2<sup>k</sup>.
191
- </p>
192
- </div>
193
- </section>
194
-
195
- <section id="check">
196
- <h2>Check (harness)</h2>
197
- <div id="check-body"></div>
198
- </section>
199
- </main>
200
-
201
- <script>
202
- (function () {
203
- 'use strict';
204
-
205
- // ------------------ Core Collatz utilities (BigInt) ------------------
206
- const ZERO = 0n,
207
- ONE = 1n,
208
- TWO = 2n,
209
- THREE = 3n;
210
-
211
- function isEven(n) {
212
- return (n & ONE) === ZERO;
213
- }
214
- function T(n) {
215
- return isEven(n) ? n / TWO : THREE * n + ONE;
216
- }
217
-
218
- function collatzStats(n0, maxSteps = 1000000) {
219
- // Returns {stepsTo1, stoppingTime, peak, trajectory}
220
- // All values BigInt except step counts (Number). Trajectory capped if huge.
221
- n0 = BigInt(n0);
222
- if (n0 <= ZERO) throw new Error('n must be a positive integer');
223
-
224
- let n = n0;
225
- let stepsTo1 = 0;
226
- let stoppingTime = null;
227
- let peak = n0;
228
- const traj = [n0];
229
-
230
- for (let k = 0; k < maxSteps; k++) {
231
- if (n === ONE) {
232
- stepsTo1 = k;
233
- break;
234
- }
235
- n = T(n);
236
- if (n > peak) peak = n;
237
- if (stoppingTime === null && n < n0) stoppingTime = k + 1;
238
- if (traj.length < 512) traj.push(n); // keep first 512 for display
239
- if (k + 1 === maxSteps) throw new Error('Exceeded max steps without reaching 1');
240
- }
241
- if (stoppingTime === null) stoppingTime = stepsTo1; // if it only dipped below once it hit 1
242
-
243
- return { stepsTo1, stoppingTime, peak, trajectory: traj };
244
- }
245
-
246
- // memoization for total stopping time (optional speedup)
247
- const memo = new Map([[ONE, 0]]); // stepsTo1(1) = 0
248
- function stepsTo1Memo(n) {
249
- n = BigInt(n);
250
- if (memo.has(n)) return memo.get(n);
251
- const nxt = T(n);
252
- const v = 1 + stepsTo1Memo(nxt);
253
- memo.set(n, v);
254
- return v;
255
- }
256
-
257
- // Format helpers
258
- const fmt = {
259
- int: (x) => x.toString(),
260
- commas: (x) => x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','),
261
- };
262
-
263
- // ------------------ Answer: sample table + interactive n ------------------
264
- const samples = [1, 2, 3, 6, 7, 9, 13, 27, 97, 871, 6171, 77031, 837799];
265
- const answerBody = document.getElementById('answer-body');
266
-
267
- function renderSamples() {
268
- let html =
269
- '<table class="tbl mono small"><thead><tr><th>n</th><th>σ(n)</th><th>σ∞(n)</th><th>peak</th><th>prefix of trajectory</th></tr></thead><tbody>';
270
- for (const n of samples) {
271
- const s = collatzStats(n);
272
- const prefix = s.trajectory.slice(0, 20).map(fmt.int).join(' → ');
273
- html += `<tr>
274
- <td>${fmt.commas(BigInt(n))}</td>
275
- <td>${s.stoppingTime}</td>
276
- <td>${s.stepsTo1}</td>
277
- <td>${fmt.commas(s.peak)}</td>
278
- <td>${prefix}${s.trajectory.length >= 512 ? ' → …' : ''}</td>
279
- </tr>`;
280
- }
281
- html += '</tbody></table>';
282
-
283
- // Interactive panel
284
- html += `<div class="row" style="margin-top:10px">
285
- <span class="muted small">Computed trajectory length is capped to the first 512 terms for display.</span>
286
- </div>
287
- <div id="interactive" class="mono small" style="margin-top:8px"></div>`;
288
-
289
- answerBody.innerHTML = html;
290
- }
291
-
292
- function computeInteractive() {
293
- const input = document.getElementById('nInput');
294
- let raw = (input.value || '').trim();
295
- if (!/^\d+$/.test(raw) || raw === '0') {
296
- document.getElementById('interactive').textContent = 'Please enter a positive integer.';
297
- return;
298
- }
299
- const n = BigInt(raw);
300
- const s = collatzStats(n);
301
- const traj =
302
- s.trajectory.map(fmt.int).join(' → ') + (s.trajectory[s.trajectory.length - 1] !== 1n ? ' → …' : '');
303
- const lines = [
304
- `n = ${fmt.commas(n)}`,
305
- `stopping time σ(n) = ${s.stoppingTime}`,
306
- `total stopping time σ∞(n) = ${s.stepsTo1}`,
307
- `peak = ${fmt.commas(s.peak)}`,
308
- `trajectory (prefix) = ${traj}`,
309
- ];
310
- const pre = document.createElement('pre');
311
- pre.className = 'mono';
312
- pre.style.whiteSpace = 'pre-wrap';
313
- pre.textContent = lines.join('\n');
314
- const host = document.getElementById('interactive');
315
- host.replaceChildren(pre);
316
- }
317
-
318
- // ------------------ Check (harness) ------------------
319
- function runChecks() {
320
- const out = [];
321
- let okAll = true;
322
-
323
- // (1) Powers of two
324
- let okPow2 = true;
325
- for (let k = 0; k <= 40; k++) {
326
- const n = 1n << BigInt(k);
327
- const s = collatzStats(n);
328
- const cond = s.stepsTo1 === k && s.peak === n;
329
- if (!cond) {
330
- okPow2 = false;
331
- out.push(` power-of-two failed at 2^${k}`);
332
- break;
333
- }
334
- }
335
- out.push(`Powers-of-two check σ∞(2^k)=k and peak=2^k for k=0..40: ${okPow2}`);
336
- okAll = okAll && okPow2;
337
-
338
- // (2) Termination for n in [1..20000]
339
- let okTerm = true;
340
- const LIMIT = 20000;
341
- for (let i = 1; i <= LIMIT; i++) {
342
- const steps = stepsTo1Memo(i);
343
- if (typeof steps !== 'number') {
344
- /* steps is Number */
345
- }
346
- if (steps < 0 || !Number.isFinite(steps)) {
347
- okTerm = false;
348
- out.push(` bad steps at ${i}`);
349
- break;
350
- }
351
- }
352
- out.push(`Terminates to 1 for n ∈ [1, ${LIMIT}]: ${okTerm}`);
353
- okAll = okAll && okTerm;
354
-
355
- // (3) Parity transition sanity (random sample)
356
- function rndInt(a, b) {
357
- return Math.floor(Math.random() * (b - a + 1)) + a;
358
- }
359
- let okParity = true;
360
- for (let j = 0; j < 200 && okParity; j++) {
361
- const n = BigInt(rndInt(1, 1000000));
362
- const next = T(n);
363
- if (isEven(n)) {
364
- if (next !== n / 2n) {
365
- okParity = false;
366
- out.push(` parity mismatch at even n=${n}`);
367
- }
368
- } else {
369
- if (next !== 3n * n + 1n) {
370
- okParity = false;
371
- out.push(` parity mismatch at odd n=${n}`);
372
- }
373
- }
374
- }
375
- out.push(`Parity rule T(n) consistency on random sample: ${okParity}`);
376
- okAll = okAll && okParity;
377
-
378
- out.push('');
379
- out.push(`All checks passed? ${okAll}`);
380
- return out;
381
- }
382
-
383
- function renderChecks() {
384
- const lines = runChecks();
385
- const wrap = document.getElementById('check-body');
386
- const pre = document.createElement('pre');
387
- pre.className = 'mono';
388
- pre.style.whiteSpace = 'pre-wrap';
389
- pre.textContent = lines.join('\n');
390
- wrap.replaceChildren(pre);
391
- }
392
-
393
- // Wire up
394
- document.getElementById('runBtn').addEventListener('click', computeInteractive);
395
-
396
- // Render initial content
397
- renderSamples();
398
- computeInteractive();
399
- renderChecks();
400
- })();
401
- </script>
402
- </body>
403
- </html>