12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- import math, sequtils, strscans, strutils, tables
-
- type
- State = tuple[start: int, plants: string]
-
- const
- iterations = 50_000_000_000
-
- func score(state: State): int =
- for i, c in state.plants:
- if c == '#':
- result += i + state.start
-
-
- func iterate(state: State, rules: ref Table[string, char]): State =
- let
- input = "...." & state.plants & "...."
- start = state.start - 2
-
- var
- output = ""
- left = -1
-
- for i in 0..input.len - 5:
- let val = rules[input.substr(i, i + 4)]
- output &= val
- if left == -1 and val == '#':
- left = i - 1
-
- (start + left, output.substr(left).strip(leading=false, chars={'.'}))
-
-
- proc solve(initialState: State, rules: ref Table[string, char]) =
- var state = initialState
-
- for i in 1..iterations:
- var nextState = iterate(state, rules)
-
- if i == 20:
- echo nextState.score
-
- if state.plants == nextState.plants:
- # Same pattern of plants, they're just wandering off somewhere.
- let
- difference = nextState.score - state.score
- remaining = iterations - i
- score = nextState.score + difference * remaining
- echo score
- return
-
- state = nextState
-
- # If we reach here then the pattern didn't repeat, and it's
- # probably taken an *awfully* long time.
- echo state.score
-
-
- var
- rules = newTable[string, char]()
- lines = readFile("data/12.txt").strip.splitlines
- initialState: State = (0, lines[0].strip.substr(15))
-
- for line in lines[2..lines.len-1]:
- if line.strip.len > 0:
- rules.add(line.substr(0,4), line.substr(9)[0])
-
- solve(initialState, rules)
|