# nix eval -f ./day_1.nix part1 # nix eval -f ./day_1.nix part1 --arg input 'builtins.readFile ./puzzle_cache/day_1_1' # nix eval -f ./day_1.nix part2 # nix eval -f ./day_1.nix part2 --arg input 'builtins.readFile ./puzzle_cache/day_1_1' { input ? (builtins.readFile ./puzzle_cache/day_1_0), }: with builtins; with import ./utils.nix; let # Split into non-empty lines lines = split "\n" input; # Parse a line like "L68" or "R14" parseLine = line: { dir = builtins.substring 0 1 line; dist = toIntBase10 (builtins.substring 1 (builtins.stringLength line - 1) line); }; rotations = map parseLine lines; countZerosDuring = position: dir: dist: if dir == "R" then floor ((position + dist) / 100.0) - floor (position / 100.0) else if dir == "L" then floor ((position -1) / 100.0) - floor ((position - dist - 1) / 100.0) else builtins.throw "Invalid direction: ${dir}"; # Fold over the list to simulate the dial step = state: rot: let position = if rot.dir == "L" then mod (state.position - rot.dist) 100 else if rot.dir == "R" then mod (state.position + rot.dist) 100 else builtins.trace "Invalid direction: ${rot.dir}" state.position; countZeroPassed = state.countZeroPassed + (countZerosDuring state.position rot.dir rot.dist); countZero = state.countZero + (if position == 0 then 1 else 0); in { inherit position countZero countZeroPassed; }; initialState = { position = 50; countZero = 0; countZeroPassed = 0; }; finalState = builtins.foldl' step initialState rotations; in { part1 = finalState.countZero; part2 = finalState.countZeroPassed; # 6689 should be part 2 }