diff --git a/d14.py b/d14.py new file mode 100644 index 0000000..db3f902 --- /dev/null +++ b/d14.py @@ -0,0 +1,88 @@ +from lib import * + +EXAMPLE = """ +O....#.... +O.OO#....# +.....##... +OO.#O....O +.O.....O#. +O.#..O.#.# +..O..#O..O +.......O.. +#....###.. +#OO..#.... +""" + +def get_nth_elem(xs, n): + """ Find the nth element of a repeating sequence. """ + found = set() + x = None + for (i, x) in enumerate(xs): + if x in found: + break + found.add(x) + if i is None: + raise Exception("No repeating sequence.") + first_repeat = i + initial_sequence_length = xs.index(x) + repeating_sequence_length = first_repeat - xs.index(x) + + adjusted_n = n - initial_sequence_length + position_in_repeating_sequence = adjusted_n % repeating_sequence_length + element = xs[initial_sequence_length + position_in_repeating_sequence] + return element + +def solve(i: Input, second=False): + res = 0 + g = i.grid2() + if second: + dirs = [Grid2D.N, Grid2D.W, Grid2D.S, Grid2D.E] + cycles = 1000000000 + else: + dirs = [Grid2D.N] + cycles = 1 + + fs = {} + v = [] + for i in range(cycles): + h = hash(tuple(g.find('O'))) + fs[h] = tuple(g.find('O')) + v.append(h) + if v.count(h) > 1: + break + for d in dirs: + moved = True + while moved: + moved = False + for r in g.find('O'): + rn = add2(r, d) + if rn in g and g[rn] == '.': + g[r] = '.' + g[rn] = 'O' + moved = True + + if second: + h = get_nth_elem(v, 1000000000) + os = fs[h] + for r, c in os: + s = g.n_rows - r + res += s + else: + for r, c in g.find('O'): + s = g.n_rows - r + res += s + return res + +def main(): + DAY_INPUT = "i14.txt" + + print("Example 1:", solve(Input(EXAMPLE))) + print("Solution 1:", solve(Input(DAY_INPUT))) + # 5:55 + + print("Example 2:", solve(Input(EXAMPLE), True)) + print("Solution 2:", solve(Input(DAY_INPUT), True)) + # 48:00 + +if __name__ == "__main__": + main()