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/collatz.html
DELETED
|
@@ -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 if n is even; 3n+1 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> < 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>
|