def largest_value(instructions): largest_ever = 0 for name in register_names(instructions): locals()[name] = 0 for instruction in instructions: exec(translate(instruction)) largest_ever = max(largest_ever, _largest_int(locals().values())) locals_copy = locals().copy() locals_copy.pop('largest_ever') largest_at_end = _largest_int(locals_copy.values()) return largest_at_end, largest_ever def _largest_int(values): ints = [value for value in values if isinstance(value, int)] return max(ints) if ints else 0 def register_names(instructions): return {instruction.split()[0] for instruction in instructions} def translate(instruction): instruction = instruction.replace('inc', '+=').replace('dec', '-=') left, right = instruction.split(' if ') return f'if {right}: {left}' if __name__ == '__main__': print(largest_value(input_rows(8)))
edge_programs = {program_from_id[id_]} next_edge_programs = set() while edge_programs: for edge_program in edge_programs: interior_programs.add(edge_program) for connection_id in edge_program.connections: connected_program = program_from_id[connection_id] if connected_program not in interior_programs | \ edge_programs: next_edge_programs.add(connected_program) edge_programs = next_edge_programs next_edge_programs = set() return interior_programs def groups(strings): ids = set() output = [] for id_, _ in enumerate(strings): if id_ not in ids: group = group_including_program(strings, id_) group_ids = {program.id for program in group} output.append(group) ids = ids | group_ids return output if __name__ == '__main__': print(len(group_including_program(input_rows(12), 0))) print(len(groups(input_rows(12))))
@classmethod def _all_bridges_from_components(cls, components_left, bridge=None): if not bridge: bridge = Bridge() else: yield bridge for component in bridge.filter_compatible(components_left): new_components_left = [c for c in components_left if not c is component] yield from cls._all_bridges_from_components( new_components_left, bridge.add(component)) @classmethod def strongest_bridge_from_component_strings(cls, strings): return max(b.strength for b in cls.all_bridges_from_component_strings( strings)) @classmethod def strength_of_longest_bridge(cls, strings): bridges = list(cls.all_bridges_from_component_strings(strings)) max_length = len(max(bridges, key=lambda x: len(x))) max_length_bridges = [bridge for bridge in bridges if len(bridge) == max_length] return max(max_length_bridges, key=lambda x: x.strength).strength if __name__ == '__main__': print(Bridge.strongest_bridge_from_component_strings(input_rows(24))) print(Bridge.strength_of_longest_bridge(input_rows(24)))
from program import BaseProgram, FirstRcvReachedException from util import input_rows class SoundRecoverProgram(BaseProgram): def __init__(self, break_on_first_rcv): super().__init__() self._break_on_first_rcv = break_on_first_rcv self._most_recently_played_sound = None def recovered_frequency(self, instructions): try: self.follow_instructions(instructions) except FirstRcvReachedException as e: return e.args[0] def _rcv(self, params): if self._break_on_first_rcv and self._to_value(params[0]) != 0: raise FirstRcvReachedException(self._most_recently_played_sound) def _snd(self, params): self._most_recently_played_sound = self._to_value(params[0]) if __name__ == '__main__': computer = SoundRecoverProgram(break_on_first_rcv=True) print(computer.recovered_frequency(input_rows(18)))
from util import input_rows INPUT = input_rows(9)[0] def score(s): return score_and_garbage_count(s)[0] def score_and_garbage_count(s): level = 0 result = 0 garbage_count = 0 in_garbage = False iterator = iter(s) for c in iterator: if c == '!': next(iterator, None) continue elif c == '>': in_garbage = False elif not in_garbage: if c == '{': level += 1 elif c == '}': result += level level -= 1 if c == '<': in_garbage = True else: # in_garbage == True garbage_count += 1
def main(): print(solve_captcha(input_rows(1)[0])) print(solve_captcha_part_two(input_rows(1)[0]))
def test_missing_square(self): book = EnhancementBook.from_strings(input_rows(21)) assert Square.from_string('###/###/###') in book
distance += 1 def intersecting_position(self): if self.pos1 == self.pos2: return self.pos1 source_positions = { direction: Position.from_position(self.pos1) for direction in Position.DIRECTIONS } target_positions = { direction: Position.from_position(self.pos2) for direction in Position.DIRECTIONS } visited_positions = {self.pos1, self.pos2} while True: source_positions = self.walk_outwards(source_positions) for position in source_positions.values(): if position in visited_positions: return position visited_positions.add(position) target_positions = self.walk_outwards(target_positions) for position in target_positions.values(): if position in visited_positions: return position visited_positions.add(position) if __name__ == '__main__': input_ = input_rows(11)[0] print(distance_from_string(input_))
adjacent_position = self._position + Direction(direction_string) if not adjacent_position == self._previous_position: yield adjacent_position class Diagram: def __init__(self, table): self._table = table def character(self, position): return self._table[position.y][position.x] @property def start_positions(self): for i, s in enumerate(self._table[0]): if not s == ' ': return Position(x=i, y=0), Position(x=i, y=-1) @property def width(self): return len(self._table[0]) if __name__ == '__main__': diagram = Diagram(input_rows(19, strip=False)) packet = Packet(diagram) while not packet.finished: packet.step_to_next_position() print(packet.letters) print(packet.step_count)
return set(p for p in self._particles if p.distance_from_origin == self._minimum_distance_to_origin(particles)) class CollidingSwarm(ParticleSwarm): @property def count_after_collisions(self): # Not a pretty solution, but checking if all were # scattering was too slow. for i in range(100): self._tick() self._remove_colliding() return len(self._particles) def _remove_colliding(self): particles_from_position = defaultdict(set) for particle in self._particles: particles_from_position[tuple(particle.position)].add(particle) for _, particles in particles_from_position.items(): if len(particles) > 1: for particle in particles: self._particles.remove(particle) if __name__ == '__main__': swarm = ParticleSwarm.from_strings(input_rows(20)) print(swarm.index_closest_to_origin_long_term()) swarm = CollidingSwarm.from_strings(input_rows(20)) print(swarm.count_after_collisions)
def main(): programs = ProgramParser.create_programs(input_rows(7)) p = bottom_program(programs) print(p.name) print(correct_weight_of_faulty_program(programs))
from util import input_rows def count_steps(list_, change_function): list_ = list(list_) index = 0 steps = 0 while index < len(list_): value = list_[index] list_[index] = change_function(value) index += value steps += 1 return steps list_ = [int(s) for s in (input_rows(5))] print(count_steps(list_, lambda x: x + 1)) print(count_steps(list_, lambda x: x + 1 if x < 3 else x - 1))
def __init__(self, strings): self._dict = { int(s.split(': ')[0]): Layer(int(s.split(': ')[-1])) for s in strings } def severity(self, layer_index, delay): if self._dict[layer_index].scanner_location(delay + layer_index) == 0: return self._dict[layer_index].depth * layer_index else: return 0 def total_severity(self, delay=0): return sum(self.severity(i, delay) for i in self._dict) def caught(self, delay=0): for i in self._dict: if self._dict[i].scanner_location(delay + i) == 0: return True return False def first_delay_without_being_caught(self): for delay in itertools.count(): if not self.caught(delay): return delay if __name__ == '__main__': print(Layers(input_rows(13)).total_severity()) print(Layers.first_delay_without_being_caught(input_rows(13)))
""".split('\n') class ExperimentalProgram(BaseProgram): def __init__(self): super().__init__() self.mul_count = 0 def _mul(self, params): self.mul_count += 1 super()._mul(params) def _jnz(self, params): if self._to_value(params[0]) != 0: self._index += self._to_value(params[1]) - 1 def _sub(self, params): self._registers[params[0]] -= self._to_value(params[1]) if __name__ == '__main__': input_ = input_rows(23) # program = ExperimentalProgram() # program.follow_instructions(input_) # print(program.mul_count) program = ExperimentalProgram() program._registers['a'] = 1 program.follow_instructions(INSTRUCTIONS) print(program._registers['h'])
def __getitem__(self, item): return self._translations[item] def __iter__(self): return iter(self._translations) @classmethod def from_strings(cls, strings): dict_ = {} for string in strings: source, _, target = string.split() source_square = Square.from_string(source) target_square = Square.from_string(target) for rotated_source_square in source_square.rotations_and_flips(): dict_[rotated_source_square] = target_square return EnhancementBook(dict_) if __name__ == '__main__': book = EnhancementBook.from_strings(input_rows(21)) square = Square.from_string('.#./..#/###') for _ in range(5): square = square.iterate(book) print(square.count_pixels_on()) square = Square.from_string('.#./..#/###') for _ in range(18): square = square.iterate(book) print(square.count_pixels_on())
program._peer_program = self def send(self, value): self._message_queue.appendleft(value) def _snd(self, params): self.send_count += 1 self._peer_program.send(self._to_value(params[0])) def _rcv(self, params): if len(self._message_queue) == 0: self.waiting = True self._index -= 1 # stay in place return self._registers[params[0]] = self._message_queue.pop() self.waiting = False def send_count_of_second_program_at_deadlock(programs, instructions): programs[0].peer(programs[1]) while any([not p.waiting for p in programs]): for p in programs: p.follow_instruction(instructions) return programs[1].send_count if __name__ == '__main__': p0 = DuetProgram(0) p1 = DuetProgram(1) print(send_count_of_second_program_at_deadlock([p0, p1], input_rows(18)))
while True: try: row = next(strings) except StopIteration: return cls(state_dict) if 'In state' in row: state_name = cls._string_between(row, 'In state ', ':') next(strings) action_when_0 = cls.action_from_iterator(strings) next(strings) action_when_1 = cls.action_from_iterator(strings) state_dict[state_name] = State(action_when_0, action_when_1) @classmethod def action_from_iterator(cls, iterator): write = cls._string_between(next(iterator), 'value ', '.') direction = cls._string_between(next(iterator), 'the ', '.') direction_int = -1 if direction == 'left' else 1 next_state = cls._string_between(next(iterator), 'state ', '.') return Action(write, direction_int, next_state) @staticmethod def _string_between(string, before, after): return string.split(before)[-1].split(after)[0] if __name__ == '__main__': machine = TuringMachine.from_strings(input_rows(25)) machine.run(12368930) print(machine.checksum())
def flag(self, position): self._dict[position] = 'F' def __str__(self): output = [] first_row = min(self._dict.keys(), key=lambda x: x[1])[1] last_row = max(self._dict.keys(), key=lambda x: x[1])[1] first_column = min(self._dict.keys(), key=lambda x: x[0])[0] last_column = max(self._dict.keys(), key=lambda x: x[0])[0] for y in range(first_row, last_row + 1): current_string = '' for x in range(first_column, last_column + 1): current_string += self._dict[(x, y)] + ' ' output.append(current_string) return '\n'.join(output) if __name__ == '__main__': grid = Grid(input_rows(22)) virus = Virus(grid, (12, 12)) for _ in range(10000): virus._burst() print(virus._infect_count) grid2 = Grid2(input_rows(22)) virus2 = Virus2(grid2, (12, 12)) # Don't name classes this way, easy typo for _ in range(10000000): virus2._burst() print(virus2._infect_count)