def _log_packet(packet: tuple[int, int, int, list]) -> None: log(packet) version, type_id, val, sub_packets = packet if type_id == 4: log("/".join([str(version), str(type_id), str(val)])) else: [_log_packet(p) for p in sub_packets]
def _output_2(space: set): if not __debug__: return w = defaultdict(set) [w[cell[0]].add((cell[1], cell[2], cell[3])) for cell in space] wz = defaultdict(set) for k, v in w.items(): z = defaultdict(set) [z[cell[0]].add((cell[1], cell[2])) for cell in v] wz[k] = z result = list[str]() for w in sorted(wz.keys()): min_z = min(z for z in wz[w].keys() if z >= 0) min_c = min(c for r, c in wz[w][min_z]) max_c = max(c for r, c in wz[w][min_z]) min_r = min(r for r, c in wz[w][min_z]) max_r = max(r for r, c in wz[w][min_z]) for z in sorted(wz[w].keys()): result.append(f"z={z}, w={w}") for r in range(min_r, max_r + 1): line = "" for c in range(min_c, max_c + 1): line += (ON if (r, c) in wz[w][z] else OFF) result.append(line) result.append(" ") log(result)
def _solve_vm(inputs: tuple[str], init_c: int) -> int: inss = Assembunny.parse(inputs) program = Program(Assembunny.translate(inss)) program.set_register_value("c", init_c) VirtualMachine().run_program(program) log(program.registers["a"]) return program.registers["a"]
def _run_generations(space: set[tuple[int, ...]], generations: int, neighbour_factory, output) -> set[tuple[int, ...]]: for i in range(generations): log(f"GENERATION #{i+1}") output(space := _next_generation(space, neighbour_factory)) log(neighbour_factory.cache_info()) return space
def _log_tree(tree): if type(tree) == list: for tree_item in tree: _log_tree(tree_item) else: for tree_item in tree: log(tree_item)
def _build_edges(inputs: tuple[str]) -> frozenset[Edge]: parsed_lines = [_parse_line(line) for line in inputs] log(parsed_lines) return frozenset({ Edge(parsed_line[0], dst[1], dst[0]) for parsed_line in parsed_lines for dst in parsed_line[1] })
def _check_valid_2(input_: str) -> bool: first, second, wanted, passw = _parse(input_) first_matched = passw[first - 1] == wanted second_matched = passw[second - 1] == wanted check = xor(first_matched, second_matched) log(f"{input_}, {(first, second, wanted, passw)}, {check}") return check
def part_2(inputs: tuple[str]) -> int: inputs_2 = (inputs[0], inputs[1], inputs[2], " #D#C#B#A#", " #D#B#A#C#", inputs[3], inputs[4]) diagram = _parse(inputs_2) log(diagram) diagram.assert_valid() return _solve(diagram)
def part_1(inputs: tuple[str]) -> int: _foods, ingredients, allergens, rules = _parse(inputs) foods = Foods(_foods) all_ingredients = [i for i in foods.all_ingredients()] i_with_a = _find_i_for_a(foods, allergens) log(i_with_a) ing = {_[1] for _ in i_with_a} return sum([1 for i in all_ingredients if i not in ing])
def _tgl(self, program: Program, instruction: Instruction, ip: int): log(instruction.opcode + str(instruction.operands)) register, = instruction.operands if register in program.registers: idx = ip + int(program.registers[register]) if 0 <= idx < len(program.instructions): new_ins = self._toggle_instruction(program.instructions[idx]) program.replace_instruction(idx, new_ins) program.move_instruction_pointer(1)
def _ji1(self, program: Program, instruction: Instruction, ip: int): log(instruction.opcode + str(instruction.operands)) (register, count) = instruction.operands if register in program.registers \ and program.registers[register] == 1: program.move_instruction_pointer(count) else: program.move_instruction_pointer(1) log(program.registers)
def _find_max_score(ingredients: list[Ingredient], calories_target: int = None) -> int: max_score = 0 for measure in _generate_measures(len(ingredients)): score = _caclulate_score(ingredients, measure, calories_target) if score > max_score: max_score = score log(max_score) return max_score
def part_2(inputs: tuple[str]) -> int: scores = sorted( reduce(lambda a, b: 5 * a + b, (INCOMPLETE_SCORES[x] for x in result.incomplete)) for result in filter(lambda x: x.incomplete is not None, ( _check(line) for line in inputs))) log(scores) assert len(scores) % 2 == 1 return scores[len(scores) // 2]
def part_2(inputs: tuple[str]) -> str: _foods, ingredients, allergens, rules = _parse(inputs) foods = Foods(_foods) i_with_a = list(_find_i_for_a(foods, allergens)) log(i_with_a) i_with_a.sort(key=lambda x: x[0]) log(i_with_a) ings = [_[1] for _ in i_with_a] return ",".join(ings)
def part_1(inputs: tuple[str]) -> int: rules, my_ticket, tickets = parse(inputs) log(rules) log(tickets) return sum([ _ for _ in [ __ for t in tickets for __ in _get_invalid_values(t, rules) ] ])
def _mul(self, program: Program, instruction: Instruction, ip: int): log(instruction.opcode + str(instruction.operands)) (register, value) = instruction.operands new_value = value \ if register not in program.registers \ else program.registers[register] * value program.set_register_value(register, new_value) program.move_instruction_pointer(1) log(program.registers)
def part_1(inputs: tuple[str]) -> int: log(inputs) instructions = _parse(inputs) program = _build_program(instructions) try: VirtualMachine().run_program(program) except RuntimeError: pass return program.registers["ACC"]
def part_2(inputs: tuple[str]) -> int: navs = _parse(inputs) start = Waypoint(10, 1) navigation = NavigationWithWaypoint(Position(0, 0), start) log(navigation) for nav in navs: _navigate_with_waypoint(navigation, nav) log(navigation) return abs(navigation.position.x) + abs(navigation.position.y)
def _check_valid_1(line: str) -> bool: colons = line.count(":") has_cid = "cid:" in line valid = colons == 8 or (colons == 7 and not has_cid) if valid: log(f"colons: {colons}, has_cid: {has_cid} -> valid ({line})") else: log(f"colons: {colons}, has_cid: {has_cid} -> INVALID ({line})") return valid
def part_1(inputs: tuple[str]) -> str: assert len(inputs) == 1 index = 0 result = "" for i in range(8): log(i) val, index = _find_md5_starting_with_5_zeroes(inputs[0], index) result += val[5] log(result) return result
def part_1(inputs: tuple[str]) -> int: navs = _parse(inputs) start = EAST navigation = NavigationWithHeading(position=Position(0, 0), heading=Headings[start].value) log(navigation) for nav in navs: _navigate_with_heading(navigation, nav) log(navigation) return abs(navigation.position.x) + abs(navigation.position.y)
def _solve(inputs: tuple[str], in_bounds, get) -> str: code = str() start = Position.of(0, 0) for ins in inputs: navigation = _navigate(ins, start, in_bounds) last = navigation.get_visited_positions()[-1] log(last) code += get(last) log(code) start = last return code
def part_1(inputs: tuple[str]) -> int: rules, messages = _parse(inputs) # log(rules) # log(messages) rule = _construct_rule(rules) assert len(rules) == 1 assert rules.keys() == {0} regex = _to_regex(rule) log(regex) return sum([1 for message in messages if re.match(regex, message)])
def _do_part_1(inputs: tuple[str], window_size: int) -> int: inputs = _parse(inputs) log(inputs) _range = range(window_size, len(inputs)) for i in _range: n = inputs[i] search_window = inputs[i - window_size:i] log(search_window) if find_two_summands(search_window, sum_=n) is None: return n raise ValueError("Unsolvable")
def _play(starting_numbers: tuple[int], number_of_turns: int) -> int: log(f"{starting_numbers} ({number_of_turns} turns)") turns = [-1] * number_of_turns for i, n in enumerate(starting_numbers[:-1], start=1): turns[n] = i prev = starting_numbers[-1] for i in range(len(starting_numbers), number_of_turns): prev_prev = turns[prev] turns[prev] = i prev = 0 if prev_prev == -1 else i - prev_prev return prev
def _split_literal(bin_data: str, i: int) -> tuple[int, int]: log("literal") val = "" while True: proceed = bin_data[i] val += bin_data[i+1:i+5] i += 5 if proceed == '0': break log(f"value: {val} ({_bin2dec(val)})") return val, i
def _build_program(lines: list[Instruction_]) -> Program: log(lines) instructions = list[Instruction]() for line in lines: line.check_valid_operation() if line.operation == "nop": instructions.append(Instruction.NOP()) elif line.operation == "acc": instructions.append(Instruction.ADD("ACC", line.argument)) elif line.operation == "jmp": instructions.append(Instruction.JMP(line.argument)) return Program(instructions, inf_loop_treshold=1)
def _run_program(inputs: tuple[str], init_a) -> int: inss = Assembunny.parse(inputs) output = list() program = Program(Assembunny.translate(inss), inf_loop_treshold=6_000, output_consumer=lambda s: output.append(s)) log(program.instructions) program.set_register_value("a", init_a) try: VirtualMachine().run_program(program) except RuntimeError: return output
def _find_count_of_equilibrium(inputs: tuple[str], strategy, tolerance: int) -> int: global the_grid the_grid = list(inputs) grid = the_grid log(grid) while True: new_grid, changed = _run_cycle(grid, strategy, tolerance) log(new_grid) if not changed: return sum(row.count(OCCUPIED) for row in grid) grid = new_grid
def _set(self, program: Program, instruction: Instruction, ip: int): log(instruction.opcode + str(instruction.operands)) (register, value) = instruction.operands if str(value).startswith("*"): value = value[1:] if value in program.registers: program.set_register_value(register, int(program.registers[value])) else: program.set_register_value(register, int(value)) program.move_instruction_pointer(1) log(program.registers)