Last active
March 31, 2026 12:58
-
-
Save brookjordan/f0cb0c01278e78d18f4ba0841df11d3c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Outputs something like: | |
| * | |
| * Top 5: | |
| * 1. 96282600 (36.5) — pair 00, palindrome 62826, ends-00, touches: pair 00 + palindrome 62826 | |
| * 2. 97557734 (32.3) — near-run 975, pair 55, pair 77, palindrome 7557, overlaps: near-run 975 ∩ pair 55, overlaps: near-run 975 ∩ palindrome 7557, touches: pair 55 + pair 77, overlaps: pair 77 ∩ palindrome 7557 | |
| * 3. 96699348 (31.6) — pair 66, pair 99, palindrome 9669, touches: pair 66 + pair 99, overlaps: pair 99 ∩ palindrome 9669 | |
| * 4. 96644427 (31.4) — triple 444, pair 66, touches: triple 444 + pair 66 | |
| * 5. 96332109 (27.9) — run4 3210, pair 33, start=end, overlaps: run4 3210 ∩ pair 33 | |
| * | |
| **/ | |
| /** export const numbers = [ | |
| * '96282600', | |
| * '97557734', | |
| * '96699348', | |
| * '96644427', | |
| * '96332109', | |
| * ] | |
| **/ | |
| import { numbers } from './numbers.ts'; | |
| type Pattern = { start: number; end: number; score: number; label: string }; | |
| function overlaps(a: Pattern, b: Pattern): boolean { | |
| return a.start < b.end && b.start < a.end; | |
| } | |
| function touches(a: Pattern, b: Pattern): boolean { | |
| return a.end === b.start || b.end === a.start; | |
| } | |
| // quadratic run scoring: 3→4, 4→10, 5→18, 6→28 | |
| const runScore = (len: number) => len < 3 ? 0 : len * len - len * 2; | |
| const nearRunScore = (len: number) => Math.round(runScore(len) * 0.4); | |
| function getPatterns(n: string): Pattern[] { | |
| const d = n.split('').map(Number); | |
| const h = n.length / 2; | |
| const patterns: Pattern[] = []; | |
| const coveredByRun = new Set<number>(); | |
| const add = (start: number, end: number, score: number, label: string) => { | |
| const containsZero = d.slice(start, end).includes(0); | |
| patterns.push({ start, end, score: containsZero ? score * 1.4 : score, label }); | |
| }; | |
| // --- Runs (strictly monotonic, quadratic scoring, no double-counting) --- | |
| for (let i = 0; i < d.length; i++) { | |
| for (const dir of ['asc', 'desc'] as const) { | |
| let len = 1; | |
| while (i + len < d.length && (dir === 'asc' ? d[i+len] === d[i+len-1]+1 : d[i+len] === d[i+len-1]-1)) len++; | |
| if (len >= 3 && !coveredByRun.has(i)) { | |
| add(i, i+len, runScore(len), `run${len} ${d.slice(i,i+len).join('')}`); | |
| for (let k = i; k < i+len; k++) coveredByRun.add(k); | |
| } | |
| } | |
| } | |
| // --- Near-runs (step of 2, asc or desc) --- | |
| const coveredByNearRun = new Set<number>(); | |
| for (let i = 0; i < d.length; i++) { | |
| for (const dir of ['asc', 'desc'] as const) { | |
| let len = 1; | |
| while (i + len < d.length && (dir === 'asc' ? d[i+len] - d[i+len-1] === 2 : d[i+len-1] - d[i+len] === 2)) len++; | |
| if (len >= 3 && !coveredByNearRun.has(i)) { | |
| add(i, i+len, nearRunScore(len), `near-run ${d.slice(i,i+len).join('')}`); | |
| for (let k = i; k < i+len; k++) coveredByNearRun.add(k); | |
| } | |
| } | |
| } | |
| // --- Triplets first, then pairs not inside a triple --- | |
| const coveredByTriple = new Array(d.length).fill(false); | |
| for (let i = 0; i < d.length - 2; i++) | |
| if (d[i] === d[i+1] && d[i+1] === d[i+2]) { | |
| add(i, i+3, 15, `triple ${d[i]}${d[i+1]}${d[i+2]}`); | |
| coveredByTriple[i] = coveredByTriple[i+1] = coveredByTriple[i+2] = true; | |
| } | |
| for (let i = 0; i < d.length - 1; i++) | |
| if (d[i] === d[i+1] && !coveredByTriple[i] && !coveredByTriple[i+1]) | |
| add(i, i+2, 6, `pair ${d[i]}${d[i+1]}`); | |
| // --- Substring palindromes (longest only per position, even=odd-1 except 8) --- | |
| const coveredByPalindrome = new Array(d.length).fill(false); | |
| for (let len = d.length; len >= 4; len--) { | |
| for (let i = 0; i <= d.length - len; i++) { | |
| const sub = n.slice(i, i+len); | |
| if (sub === sub.split('').reverse().join('')) { | |
| const alreadyCovered = Array.from({length: len}, (_, k) => coveredByPalindrome[i+k]).every(Boolean); | |
| if (!alreadyCovered) { | |
| const effectiveLen = len % 2 === 0 && len < 8 ? len - 1 : len; | |
| add(i, i+len, Math.round(4 + (effectiveLen - 1) * 1.5), `palindrome ${sub}`); | |
| for (let k = i; k < i+len; k++) coveredByPalindrome[k] = true; | |
| } | |
| } | |
| } | |
| } | |
| // --- Repeated units (2-3 digit substrings appearing 2+ times) --- | |
| // Leading echoes (unit starts at pos 0 or 1) score higher | |
| const coveredByUnit = new Set<number>(); | |
| for (let unitLen = 3; unitLen >= 2; unitLen--) { | |
| for (let i = 0; i <= n.length - unitLen * 2; i++) { | |
| const unit = n.slice(i, i + unitLen); | |
| const positions = [i]; | |
| let search = i + unitLen; | |
| while (search <= n.length - unitLen) { | |
| const idx = n.indexOf(unit, search); | |
| if (idx === -1) break; | |
| positions.push(idx); | |
| search = idx + unitLen; | |
| } | |
| if (positions.length < 2) continue; | |
| if (positions.some(p => coveredByUnit.has(p))) continue; | |
| const first = positions[0], last = positions[positions.length - 1]; | |
| const gap = last - first - unitLen; | |
| // 2-digit echoes: gap <= 2 and gap must be consistent (same spacing throughout) | |
| if (unitLen === 2 && gap > 2) continue; | |
| if (unitLen === 2) { | |
| // check the offset before first unit matches the gap | |
| const offsetBefore = first; | |
| const offsetAfter = n.length - (last + unitLen); | |
| // allow start/end of number to be 0, otherwise spacing must match gap | |
| const validSpacing = offsetBefore === offsetAfter || | |
| offsetBefore === 0 || offsetAfter === 0; | |
| if (!validSpacing) continue; | |
| } | |
| const baseScore = unitLen === 3 ? 11 : 4; | |
| const gapPenalty = Math.min(gap * 0.5, 3); | |
| const countBonus = (positions.length - 2) * 2; | |
| const leadingBonus = unitLen === 3 ? (first === 0 ? 5 : first === 1 ? 2.5 : 0) : 0; | |
| const pts = baseScore - gapPenalty + countBonus + leadingBonus; | |
| if (pts > 0) { | |
| add(first, last + unitLen, pts, `repeat${unitLen} ${unit}`); | |
| positions.forEach(p => { for (let k = p; k < p + unitLen; k++) coveredByUnit.add(k); }); | |
| } | |
| } | |
| } | |
| const repeatUnits = new Set(patterns.filter(p => p.label.startsWith('repeat')).map(p => p.label.split(' ')[1])); | |
| for (let rhymeLen = h; rhymeLen >= 2; rhymeLen--) { | |
| if (n.slice(h - rhymeLen, h) === n.slice(n.length - rhymeLen)) { | |
| const unit = n.slice(h - rhymeLen, h); | |
| if (repeatUnits.has(unit)) break; | |
| const pts = rhymeLen === h ? 6 + rhymeLen * 5 : rhymeLen === 2 ? 6 : 2 + rhymeLen * 4; | |
| add(h - rhymeLen, n.length, pts, `rhyme${rhymeLen} ...${unit}`); | |
| break; | |
| } | |
| } | |
| // --- End anchors --- | |
| if (n.endsWith('000')) add(n.length-3, n.length, 10, 'ends-000'); | |
| else if (n.endsWith('00')) add(n.length-2, n.length, 6, 'ends-00'); | |
| else if (n.endsWith('0')) add(n.length-1, n.length, 2, 'ends-0'); | |
| // --- Start/end same digit — flat bonus, no range so it can't stack overlaps --- | |
| if (d[0] === d[d.length-1]) patterns.push({ start: -1, end: -1, score: 3, label: 'start=end' }); | |
| return patterns; | |
| } | |
| function score(n: string): number { | |
| const d = n.split('').map(Number); | |
| const patterns = getPatterns(n); | |
| let s = patterns.reduce((acc, p) => acc + p.score, 0); | |
| for (let i = 0; i < patterns.length; i++) | |
| for (let j = i+1; j < patterns.length; j++) { | |
| const a = patterns[i], b = patterns[j]; | |
| const aInsideB = a.start >= b.start && a.end <= b.end; | |
| const bInsideA = b.start >= a.start && b.end <= a.end; | |
| const aPalin = a.label.startsWith('palindrome'); | |
| const bPalin = b.label.startsWith('palindrome'); | |
| if (overlaps(a, b) || (a.start === b.start && a.end === b.end)) { | |
| if ((aInsideB && bPalin) || (bInsideA && aPalin)) continue; | |
| if ((a.label.startsWith('ends-0') && b.label === 'pair 00') || | |
| (b.label.startsWith('ends-0') && a.label === 'pair 00')) continue; | |
| if (a.start < 0 || b.start < 0) continue; | |
| // rhyme/repeat are meta-patterns, exclude from overlap bonuses | |
| const isRhymeOrRepeat = (p: Pattern) => p.label.startsWith('rhyme') || p.label.startsWith('repeat'); | |
| if (isRhymeOrRepeat(a) || isRhymeOrRepeat(b)) continue; | |
| s += Math.min(a.score, b.score); | |
| } else if (touches(a, b)) { | |
| if (a.start < 0 || b.start < 0) continue; | |
| if ((a.label.startsWith('ends-0') && b.label === 'pair 00') || | |
| (b.label.startsWith('ends-0') && a.label === 'pair 00')) continue; | |
| const isAnchor = (p: Pattern) => p.label.startsWith('ends-'); | |
| const isRhymeOrRepeat = (p: Pattern) => p.label.startsWith('rhyme') || p.label.startsWith('repeat'); | |
| if (isRhymeOrRepeat(a) || isRhymeOrRepeat(b)) continue; | |
| if (isAnchor(a) || isAnchor(b)) { s += 1; continue; } | |
| const la = a.end - a.start, lb = b.end - b.start; | |
| const lens = [la, lb].sort((x, y) => x - y); | |
| s += (lens[0] === 2 && lens[1] >= 3) ? 7 : 1; | |
| } | |
| } | |
| // --- Red flag: 4 unique digits in a window with no pattern covering it --- | |
| for (let i = 0; i <= d.length - 4; i++) { | |
| const window = d.slice(i, i+4); | |
| // a pattern covers this window if it overlaps any part of it | |
| const hasPattern = patterns.some(p => p.start < i+4 && p.end > i); | |
| if (new Set(window).size >= 4 && !hasPattern) s -= 3; | |
| } | |
| // prefix | |
| if (n.startsWith('96')) s += 3; | |
| else if (n.startsWith('97')) s += 2; | |
| else if (n.startsWith('98')) s += 1; | |
| // high average digit | |
| const avg = d.reduce((a, b) => a + b, 0) / d.length; | |
| s += (avg - 5) * 1.5; | |
| // low unique digit count | |
| const unique = new Set(d).size; | |
| s += Math.max(0, (5 - unique) * 2); | |
| // all digits >= 5 | |
| if (d.every(x => x >= 5)) s += 4; | |
| return s; | |
| } | |
| function explain(n: string): string[] { | |
| const d = n.split('').map(Number); | |
| const patterns = getPatterns(n); | |
| const labels = patterns.map(p => p.label); | |
| for (let i = 0; i < patterns.length; i++) | |
| for (let j = i+1; j < patterns.length; j++) { | |
| const a = patterns[i], b = patterns[j]; | |
| const aInsideB = a.start >= b.start && a.end <= b.end; | |
| const bInsideA = b.start >= a.start && b.end <= a.end; | |
| const aPalin = a.label.startsWith('palindrome'); | |
| const bPalin = b.label.startsWith('palindrome'); | |
| const sameDigits = (a.label.startsWith('ends-0') && b.label === 'pair 00') || | |
| (b.label.startsWith('ends-0') && a.label === 'pair 00'); | |
| if (overlaps(a, b) || (a.start === b.start && a.end === b.end)) { | |
| if ((aInsideB && bPalin) || (bInsideA && aPalin) || sameDigits || a.start < 0 || b.start < 0) continue; | |
| const isRhymeOrRepeatE = (p: Pattern) => p.label.startsWith('rhyme') || p.label.startsWith('repeat'); | |
| if (isRhymeOrRepeatE(a) || isRhymeOrRepeatE(b)) continue; | |
| labels.push(`overlaps: ${a.label} ∩ ${b.label}`); | |
| } else if (touches(a, b)) { | |
| if (a.start < 0 || b.start < 0 || sameDigits) continue; | |
| const isAnchor = (p: Pattern) => p.label.startsWith('ends-'); | |
| const isRhymeOrRepeatE = (p: Pattern) => p.label.startsWith('rhyme') || p.label.startsWith('repeat'); | |
| if (isRhymeOrRepeatE(a) || isRhymeOrRepeatE(b)) continue; | |
| if (!(isAnchor(a) || isAnchor(b))) | |
| labels.push(`touches: ${a.label} + ${b.label}`); | |
| } | |
| } | |
| for (let i = 0; i <= d.length - 4; i++) { | |
| const window = d.slice(i, i+4); | |
| const hasPattern = patterns.some(p => p.start < i+4 && p.end > i); | |
| if (new Set(window).size >= 4 && !hasPattern) | |
| labels.push(`red-flag ${window.join('')}`); | |
| } | |
| return labels; | |
| } | |
| const rankedNums = numbers | |
| .map((n) => ({ n, s: score(n) })) | |
| .sort((a, b) => b.s - a.s); | |
| console.log('Top 100:'); | |
| rankedNums | |
| .slice(0, 100) | |
| .forEach(({ n, s }, i) => { | |
| const why = explain(n).join(', '); | |
| console.log(`${String(i+1).padStart(2)}. ${n} (${s.toFixed(1)}) — ${why}`); | |
| }); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yes, it’s vibe coded.
I’m organising numbers.
Sue me.