Last active
April 18, 2024 19:21
-
-
Save otac0n/0bc746fbdef6ad5bd2821b82e889a6f1 to your computer and use it in GitHub Desktop.
Simple code to compute the values of the Hydra game from Numberphile.
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
// Reference here: https://www.youtube.com/watch?v=prURA1i8Qj4 | |
var rightMost = true; | |
var step = BigInteger.Zero; | |
var initialDepth = 5; | |
// Represents a simple tree (single trunk). Length is tree depth. Root node is excluded. Value is count of leaf nodes (heads) at that depth. | |
// Nodes will always be added to the right of the implied connections. | |
var nodes = Enumerable.Range(0, initialDepth).Select((_, ix) => ix == initialDepth - 1 ? BigInteger.One : BigInteger.Zero).ToList(); | |
var timeLimit = TimeSpan.FromMinutes(0.3); | |
var sw = Stopwatch.StartNew(); | |
while (nodes.Count > 0 && sw.Elapsed < timeLimit) | |
{ | |
step++; | |
int ix; | |
if (rightMost) | |
{ | |
// Remove heads from the level that has most recently had heads added. | |
// Assuming that, as above, nodes are added left-to right, this corresponds to the lowest-index non-zero cell. | |
for (ix = 0; ix < nodes.Count - 1; ix++) | |
{ | |
if (nodes[ix] > 0) | |
{ | |
break; | |
} | |
} | |
} | |
else | |
{ | |
// Remove the furthest-away head. | |
ix = nodes.Count - 1; | |
} | |
var remaining = nodes[ix] = nodes[ix] - 1; | |
// Add new heads to the grand-parent node, n = step. | |
if (ix > 0) | |
{ | |
// OPTIMIZATION: Adding to the root node just adds more steps, effectively. | |
if (rightMost && ix == 1) | |
{ | |
// OPTIMIZATION: Don't add nodes. Instead, Add steps based on the nodes we would add, i.e. double the step number. | |
step *= 2; | |
} | |
else | |
{ | |
nodes[ix - 1] += step; | |
} | |
} | |
// When all heads are removed from a neck, it becomes a single head (leaf node). | |
if (remaining <= 0 && ix == nodes.Count - 1) | |
{ | |
nodes.RemoveAt(ix); | |
if (nodes.Count > 0) | |
{ | |
nodes[^1] += 1; | |
} | |
} | |
} | |
step.ToString().Dump(); | |
if (nodes.Count > 0) | |
{ | |
nodes.Dump("INCOMPLETE RESULTS"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment