|
/** |
|
* MAURICE MARGENSTERN'S FIBONACCI TREE TILE SYSTEM FOR HEPTAGRID {7,3} |
|
* |
|
* This module implements Margenstern's groundbreaking work on regular tilings |
|
* of the hyperbolic plane, specifically the {7,3} tiling (heptagrid) where: |
|
* - Each tile is a regular heptagon (7 sides) |
|
* - 3 heptagons meet at each vertex |
|
* - The tiling has constant negative curvature (hyperbolic geometry) |
|
* |
|
* THEORETICAL FOUNDATION: |
|
* Margenstern proved that every regular tiling of the hyperbolic plane can be |
|
* systematically addressed using a tree structure combined with Fibonacci coding. |
|
* This creates a bijective mapping between: |
|
* 1. Tiles in the infinite hyperbolic tiling |
|
* 2. Nodes in an infinite binary-like tree |
|
* 3. Positive integers via Zeckendorf representation |
|
* |
|
* KEY INSIGHTS: |
|
* - The tree structure captures the hierarchical "father-son" relationships |
|
* - Fibonacci encoding provides a unique, canonical addressing scheme |
|
* - The tree's binary nature (with controlled branching) maps to Zeckendorf's |
|
* property that every integer has unique representation as sum of non-consecutive |
|
* Fibonacci numbers |
|
* - Node colors (black/white) encode geometric properties of tiles |
|
* |
|
* APPLICATIONS: |
|
* - Computational geometry on hyperbolic surfaces |
|
* - Graph algorithms on infinite regular graphs |
|
* - Theoretical computer science (decidability problems on tilings) |
|
* - Mathematical visualization of hyperbolic space |
|
*/ |
|
|
|
/** |
|
* FIBONACCI SEQUENCE GENERATION - STANDARD DEFINITION |
|
* |
|
* Generates the standard Fibonacci sequence F(n) = F(n-1) + F(n-2) |
|
* with F(1)=1, F(2)=1, giving: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... |
|
* |
|
* This is the classical definition used in Zeckendorf representation, |
|
* where every positive integer has a unique representation as a sum |
|
* of non-consecutive Fibonacci numbers. |
|
*/ |
|
function generateFibonacci(max: number): number[] { |
|
const fib = [1, 1]; |
|
while (fib[fib.length - 1] < max) { |
|
fib.push(fib[fib.length - 1] + fib[fib.length - 2]); |
|
} |
|
return fib; |
|
} |
|
|
|
// Pre-compute Fibonacci numbers up to 100,000 for efficient lookup |
|
const FIBONACCI = generateFibonacci(100000); |
|
|
|
/** |
|
* ZECKENDORF REPRESENTATION (FIBONACCI BASE ENCODING) |
|
* |
|
* THEOREM (Zeckendorf, 1972): Every positive integer n has a unique representation |
|
* as a sum of non-consecutive Fibonacci numbers: n = F(i₁) + F(i₂) + ... + F(iₖ) |
|
* where i₁ > i₂ + 1 > i₃ + 1 > ... > iₖ ≥ 2 |
|
* |
|
* GEOMETRIC MEANING: In Margenstern's system, the Fibonacci representation |
|
* encodes the "address" or "coordinates" of a tile in the hyperbolic tiling. |
|
* Each bit corresponds to a choice in the tree traversal from root to tile. |
|
* |
|
* ALGORITHM: Greedy method starting from largest Fibonacci numbers, |
|
* skipping consecutive ones to maintain the Zeckendorf property. |
|
*/ |
|
export function toFibonacciCode(n: number): string { |
|
if (n === 0) return '0'; |
|
|
|
// Find all Fibonacci numbers that fit in n using greedy algorithm |
|
const usedFibs: boolean[] = []; |
|
let remaining = n; |
|
|
|
// Start from largest Fibonacci number and work down (greedy approach) |
|
for (let i = FIBONACCI.length - 1; i >= 1; i--) { // Start from index 1 to skip F(0)=1 |
|
if (FIBONACCI[i] <= remaining) { |
|
usedFibs[i] = true; // Mark this Fibonacci number as used |
|
remaining -= FIBONACCI[i]; // Subtract from remaining sum |
|
i--; // Skip next Fibonacci number (Zeckendorf non-consecutive property) |
|
} |
|
} |
|
|
|
// Build the code string from left to right (highest to lowest Fibonacci number used) |
|
// This creates a "big-endian" representation where leftmost bit = highest F(i) |
|
let code = ''; |
|
let started = false; |
|
for (let i = FIBONACCI.length - 1; i >= 1; i--) { |
|
if (usedFibs[i]) { |
|
code += '1'; // This Fibonacci number is part of the sum |
|
started = true; |
|
} else if (started) { |
|
code += '0'; // This Fibonacci number is not used (gap in representation) |
|
} |
|
} |
|
|
|
return code || '0'; |
|
} |
|
|
|
/** |
|
* INVERSE ZECKENDORF TRANSFORMATION |
|
* |
|
* Converts a Fibonacci base string back to its integer value. |
|
* This is the inverse operation of toFibonacciCode(). |
|
* |
|
* ALGORITHM: Sum up Fibonacci numbers corresponding to '1' bits, |
|
* where bit position determines which Fibonacci number to use. |
|
* |
|
* BIT MAPPING: The code string represents Fibonacci numbers in big-endian format: |
|
* leftmost bit → highest Fibonacci number, rightmost bit → lowest Fibonacci number |
|
* |
|
* GEOMETRIC MEANING: Reconstructs the tile address from its |
|
* binary encoding in the Fibonacci tree structure. |
|
*/ |
|
export function fromFibonacciCode(code: string): number { |
|
if (code === '0') return 0; |
|
|
|
let sum = 0; |
|
const codeLen = code.length; |
|
|
|
// Process each bit from left to right (highest to lowest Fibonacci number) |
|
for (let i = 0; i < codeLen; i++) { |
|
if (code[i] === '1') { |
|
// The leftmost bit corresponds to the highest Fibonacci number we need |
|
const fibIndex = codeLen - i; // Convert bit position to Fibonacci index |
|
if (fibIndex < FIBONACCI.length) { |
|
sum += FIBONACCI[fibIndex]; // Add corresponding Fibonacci number |
|
} |
|
} |
|
} |
|
|
|
return sum; |
|
} |
|
|
|
/** |
|
* PREFERRED SON FUNCTION - TREE STRUCTURE GENERATION |
|
* |
|
* THEORY: In Margenstern's tree model, each tile can have "children" tiles |
|
* that are geometrically adjacent in specific ways. The "preferred son" |
|
* is the canonical first child in the tree traversal. |
|
* |
|
* OPERATION: Append "00" to the Fibonacci code, which corresponds to |
|
* extending the tree path by two levels down a specific branch. |
|
* |
|
* GEOMETRIC INTERPRETATION: This finds a tile that is in a specific |
|
* geometric relationship to the parent tile in the hyperbolic tiling. |
|
* The "00" suffix encodes this relationship in the addressing scheme. |
|
* |
|
* MATHEMATICAL PROPERTY: This operation preserves the tree structure |
|
* while providing a deterministic way to generate child nodes. |
|
*/ |
|
export function preferredSon(n: number): number { |
|
return fromFibonacciCode(toFibonacciCode(n) + '00'); |
|
} |
|
|
|
/** |
|
* PARENT FUNCTION - INVERSE TREE TRAVERSAL |
|
* |
|
* THEORY: Given a tile, find its "parent" in the tree structure. |
|
* This implements the inverse of the preferred son operation. |
|
* |
|
* ALGORITHM: |
|
* 1. If the Fibonacci code ends with "00", this tile IS a preferred son |
|
* → Remove "00" suffix to get parent's address |
|
* 2. Otherwise, use heuristic (simple division by 2) |
|
* |
|
* GEOMETRIC MEANING: Moves from a child tile back to its parent tile |
|
* in the hyperbolic tiling, following the tree structure upward. |
|
* |
|
* TREE PROPERTY: This maintains the hierarchical addressing system |
|
* where each tile knows how to find its ancestors in the tree. |
|
*/ |
|
export function parent(n: number): number { |
|
const code = toFibonacciCode(n); |
|
if (code.endsWith('00')) return fromFibonacciCode(code.slice(0, -2)); |
|
return Math.floor(n / 2); // fallback estimate |
|
} |
|
|
|
/** |
|
* NODE COLORING FUNCTION - GEOMETRIC PROPERTY ENCODING |
|
* |
|
* THEORY: In Margenstern's system, tiles are colored black or white based on |
|
* their position in the tree structure. This coloring encodes geometric |
|
* properties of the tiles in the hyperbolic tiling. |
|
* |
|
* TREE GENERATION RULES: |
|
* - Root (tile 1) is WHITE |
|
* - WHITE nodes have 3 children: BLACK, WHITE, WHITE |
|
* - BLACK nodes have 2 children: BLACK, WHITE |
|
* |
|
* GEOMETRIC SIGNIFICANCE: The coloring corresponds to different types of |
|
* geometric positions in the {7,3} tiling. This may relate to: |
|
* - Distance from the center of the hyperbolic disk |
|
* - Orientation relative to geodesics |
|
* - Local geometric environment (how many edges connect to boundary) |
|
* |
|
* COMPUTATIONAL METHOD: Breadth-first tree traversal following the branching rules. |
|
* For large n, this could be optimized using the Fibonacci code directly. |
|
*/ |
|
export function isWhite(n: number): boolean { |
|
if (n === 1) return true; // root is white |
|
|
|
let queue: { id: number; type: 'white' | 'black' }[] = [{ id: 1, type: 'white' }]; |
|
let current = 2; |
|
|
|
while (queue.length > 0) { |
|
const node = queue.shift()!; |
|
const children = node.type === 'white' |
|
? [ |
|
{ id: current++, type: 'black' as const }, |
|
{ id: current++, type: 'white' as const }, |
|
{ id: current++, type: 'white' as const }, |
|
] |
|
: [ |
|
{ id: current++, type: 'black' as const }, |
|
{ id: current++, type: 'white' as const }, |
|
]; |
|
|
|
for (const child of children) { |
|
if (child.id === n) return child.type === 'white'; |
|
if (child.id > n) return false; |
|
queue.push(child); |
|
} |
|
} |
|
|
|
return false; // fallback |
|
} |
|
|
|
/** |
|
* NEIGHBOR COMPUTATION - HYPERBOLIC GEOMETRY ADJACENCY |
|
* |
|
* THEORY: In the {7,3} hyperbolic tiling, each heptagonal tile has exactly |
|
* 7 neighbors (one adjacent to each of its 7 edges). Margenstern's system |
|
* provides formulas to compute these neighbors using tree relationships. |
|
* |
|
* GEOMETRIC CONTEXT: |
|
* - {7,3} means regular heptagons with 3 meeting at each vertex |
|
* - This creates negative curvature (hyperbolic geometry) |
|
* - Unlike Euclidean tilings, the number of tiles grows exponentially with distance |
|
* |
|
* MARGENSTERN'S NEIGHBOR FORMULAS: |
|
* The 7 neighbors depend on: |
|
* - f = parent(n): the "father" tile in the tree |
|
* - s = preferredSon(n): the "preferred son" child tile |
|
* - The color (white/black) of the current tile |
|
* |
|
* FORMULA INTERPRETATION: |
|
* - WHITE tiles: [f, n-1, s-1, s, s+1, s+2, n+1] |
|
* - BLACK tiles: [f, f-1, n-1, s, s+1, s+2, n+1] |
|
* |
|
* The differences reflect the local geometric environment around |
|
* white vs black tiles in the hyperbolic tiling. |
|
* |
|
* MATHEMATICAL SIGNIFICANCE: These formulas encode the complex adjacency |
|
* relationships in hyperbolic space using simple arithmetic on the |
|
* Fibonacci-based addressing system. |
|
*/ |
|
export function getNeighbors(n: number): number[] { |
|
const f = parent(n); |
|
const s = preferredSon(n); |
|
const white = isWhite(n); |
|
|
|
return white |
|
? [f, n - 1, s - 1, s, s + 1, s + 2, n + 1] |
|
: [f, f - 1, n - 1, s, s + 1, s + 2, n + 1]; |
|
} |
|
|
|
/** |
|
* ============================================================================ |
|
* COMPREHENSIVE TEST SUITE |
|
* ============================================================================ |
|
* |
|
* This test suite validates the implementation against Margenstern's theoretical |
|
* framework and demonstrates the system's key properties: |
|
* |
|
* 1. ZECKENDORF BIJECTION: Every integer ↔ unique Fibonacci representation |
|
* 2. TREE STRUCTURE: Parent-child relationships are consistent |
|
* 3. GEOMETRIC PROPERTIES: Colors and neighbors follow the rules |
|
* 4. MATHEMATICAL CONSISTENCY: All transformations are invertible |
|
*/ |
|
function test() { |
|
console.log('--- Fibonacci Code Tests ---'); |
|
for (let n = 1; n <= 100; n++) { |
|
const code = toFibonacciCode(n); |
|
const back = fromFibonacciCode(code); |
|
console.log(`n=${n} → code=${code} → back=${back}`); |
|
if (n !== back) throw new Error(`Mismatch at ${n}`); |
|
} |
|
|
|
console.log('\n--- Node Color Test (1–20) ---'); |
|
for (let n = 1; n <= 100; n++) { |
|
const type = isWhite(n) ? 'white' : 'black'; |
|
console.log(`tile ${n}: ${type}`); |
|
} |
|
|
|
console.log('\n--- Neighbor Test for tile 6 ---'); |
|
const neighbors = getNeighbors(6); |
|
console.log('Neighbors of tile 6:', neighbors); |
|
} |
|
|
|
// Uncomment to run tests |
|
test(); |
Looking at Margenstern's discoveries through a cosmological lens reveals profound implications (in summary from Claude AI):