def axis(self) -> Vector: if self.__root__ == "N": return Vector(x=0, y=1) elif self.__root__ == "W": return Vector(x=-1, y=0) elif self.__root__ == "S": return Vector(x=0, y=-1) elif self.__root__ == "E": return Vector(x=1, y=0) else: assert_never(self.__root__)
def run_step(self) -> None: self._visited_indices.add(self._current_index) current_instruction = self.instructions[self._current_index] if isinstance(current_instruction, Acc): self._accumulator += current_instruction.value self._current_index += 1 elif isinstance(current_instruction, Nop): self._current_index += 1 elif isinstance(current_instruction, Jmp): self._current_index += current_instruction.offset else: assert_never(current_instruction.code)
def part1(self) -> int: mask = None result: Dict[int, int] = {} for instruction in self.puzzle.data: if isinstance(instruction, Mask): mask = instruction elif isinstance(instruction, MemSet): bitstring = instruction.value_as_bitstring() if mask: bitstring = mask.apply_to(bitstring) result[instruction.address] = int(bitstring, 2) else: assert_never(instruction) return sum(result.values())
def part2(self) -> int: for index, instruction in enumerate(self.puzzle.data): if instruction.code == "acc": continue elif instruction.code == "jmp": new_instruction_set = self._mutate_instruction(index, Nop) elif instruction.code == "nop": new_instruction_set = self._mutate_instruction(index, Jmp) else: assert_never(instruction.code) interpreter = Interpreter(new_instruction_set) try: return interpreter.run() except LoopDetected: pass raise NoResultFoundException
def part2(self) -> int: mask = None result: Dict[int, int] = {} for instruction in self.puzzle.data: if isinstance(instruction, Mask): mask = instruction elif isinstance(instruction, MemSet): if not mask: result[instruction.address] = instruction.value else: masked_addr = mask.apply_to_addr( instruction.address_as_bitstring()) for sub_mask in masked_addr.generate_all_values(): addr = int(sub_mask.str_repr, 2) result[addr] = instruction.value else: assert_never(instruction) return sum(result.values())
def part1(self) -> int: boat = Boat.starting_position() for instruction in self.puzzle.data: if isinstance(instruction.action, Direction): shift = instruction.action.axis * instruction.value boat.coord += shift elif instruction.action == "F": shift = boat.direction.axis * instruction.value boat.coord += shift # `action in ["L", "R"]` makes mypy fail to see we can never reach the `assert_never` (mypy 0.790) elif instruction.action == "L" or instruction.action == "R": rotation_number = instruction.value // 90 if instruction.action == "L": rotation_number *= -1 boat.direction = Direction.clockwise( from_=boat.direction)[rotation_number] else: assert_never(instruction) return boat.coord.manhattan_distance
def part2(self) -> int: boat = Boat.starting_position() for instruction in self.puzzle.data: if isinstance(instruction.action, Direction): shift = instruction.action.axis * instruction.value boat.waypoint_offset += shift elif instruction.action == "F": shift = boat.waypoint_offset * instruction.value boat.coord += shift elif instruction.action == "L" or instruction.action == "R": rotation_number = instruction.value // 90 if instruction.action == "L": rotation_number *= 3 for _ in range(rotation_number): boat.waypoint_offset = boat.waypoint_offset.rotate_clockwise( ) else: assert_never(instruction) return boat.coord.manhattan_distance