from utils import get_input_lines instr_ptr = 0 accumulator = 0 program = [] for instr, num in map(lambda x: x.split(" "), get_input_lines(__file__)): num = int(num) program.append((instr, num)) visited = set() while True: if instr_ptr in visited: break visited.add(instr_ptr) instr, num = program[instr_ptr] if instr == "nop": instr_ptr += 1 elif instr == "acc": instr_ptr += 1 accumulator += num elif instr == "jmp": instr_ptr += num else: raise ValueError(f"Unknown instruction {instr}") print(accumulator)
from utils import get_input_lines pos_x = 0 pos_y = 0 waypoint_x = 10 waypoint_y = 1 for line in get_input_lines(__file__): action = line[0] n = int(line[1:]) # Handle actions if action == "N": waypoint_y += n elif action == "S": waypoint_y -= n elif action == "E": waypoint_x += n elif action == "W": waypoint_x -= n elif action == "L": # Rotate (n//90) times CCW: (new_x, new_y) = (-old_y, old_x) for i in range(n // 90): tmp_x = waypoint_x waypoint_x = -waypoint_y waypoint_y = tmp_x elif action == "R": # Rotate (n//90) times CW: (new_x, new_y) = (old_y, -old_x) for i in range(n // 90): tmp_x = waypoint_x
from functools import reduce from utils import get_input_lines slopes = [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)] tree_count = [0] * len(slopes) x_pos = [0] * len(slopes) line_length = 0 for line_idx, line in enumerate(get_input_lines(__file__)): if line_length == 0: line_length = len(line) for idx, (slope_x, slope_y) in enumerate(slopes): if line_idx % slope_y == 0: if line[x_pos[idx]] == "#": tree_count[idx] += 1 x_pos[idx] = (x_pos[idx] + slope_x) % line_length print(reduce(lambda x, y: x * y, tree_count))
from typing import Dict, Tuple from utils import get_input_lines grid = dict() FLOOR = 0 FREE = 1 OCCUPIED = 2 x = 0 y = 0 for row in get_input_lines(__file__): x = 0 for char in row: grid[(x, y)] = FLOOR if char == "." else FREE x += 1 y += 1 cols = x rows = y def count_adjacent_occupied(x_: int, y_: int, grid_: Dict[Tuple[int, int], int]) -> int: count = 0 for x_d in [-1, 0, 1]: for y_d in [-1, 0, 1]: if x_d == 0 and y_d == 0: # Don't count own field, only neighbours continue x_d_original = x_d
from utils import get_input_lines active = set() for y, line in enumerate(get_input_lines(__file__)): for x, char in enumerate(line): if char == "#": active.add((x, y, 0)) rounds = 6 while rounds > 0: rounds -= 1 new_active = set() # Find minimum and maximum coordinates min_x, max_x = None, None min_y, max_y = None, None min_z, max_z = None, None for (x, y, z) in active: min_x = min(min_x, x) if min_x is not None else x max_x = max(max_x, x) if max_x is not None else x min_y = min(min_y, y) if min_y is not None else y max_y = max(max_y, y) if max_y is not None else y min_z = min(min_z, z) if min_z is not None else z max_z = max(max_z, z) if max_z is not None else z # Go over all cubes in the range of the active cubes for x in range(min_x - 1, max_x + 2): for y in range(min_y - 1, max_y + 2): for z in range(min_z - 1, max_z + 2):
from utils import get_input_lines arrival, bus_ids = get_input_lines(__file__) arrival = int(arrival) smallest_bus_id = None smallest_wait = None for bus_id in bus_ids.split(","): if bus_id == "x": continue bus_id = int(bus_id) bus_wait = bus_id - (arrival % bus_id) if smallest_wait is None or bus_wait < smallest_wait: smallest_wait = bus_wait smallest_bus_id = bus_id print(smallest_wait * smallest_bus_id)
from functools import reduce from typing import List from utils import get_input_lines mods = [] rems = [] for offset, bus_id in enumerate(list(get_input_lines(__file__))[1].split(",")): if bus_id == "x": continue bus_id = int(bus_id) # Use Chinese Remainder Theorem # (X mod bus_id) = k * bus_id - offset, with k such that the right hand side is not negative rhs = bus_id - offset if offset > 0 else 0 # Correct right hand side if it is too small while rhs < 0: rhs += bus_id mods.append(bus_id) rems.append(rhs) def modular_inverse(a: int, b: int) -> int: # Source: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Modular_integers t, new_t = 0, 1 r, new_r = b, a