コード例 #1
0
ファイル: day8.py プロジェクト: Godsmith/adventofcode2017
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)))
コード例 #2
0
ファイル: day12.py プロジェクト: Godsmith/adventofcode2017
    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))))
コード例 #3
0
    @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)))
コード例 #4
0
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)))
コード例 #5
0
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
コード例 #6
0
ファイル: day1.py プロジェクト: Godsmith/adventofcode2017
def main():
    print(solve_captcha(input_rows(1)[0]))
    print(solve_captcha_part_two(input_rows(1)[0]))
コード例 #7
0
 def test_missing_square(self):
     book = EnhancementBook.from_strings(input_rows(21))
     assert Square.from_string('###/###/###') in book
コード例 #8
0
ファイル: day11.py プロジェクト: Godsmith/adventofcode2017
            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_))
コード例 #9
0
            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)
コード例 #10
0
ファイル: day20.py プロジェクト: Godsmith/adventofcode2017
        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)
コード例 #11
0
def main():
    programs = ProgramParser.create_programs(input_rows(7))
    p = bottom_program(programs)
    print(p.name)
    print(correct_weight_of_faulty_program(programs))
コード例 #12
0
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))
コード例 #13
0
    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)))
コード例 #14
0
ファイル: day23.py プロジェクト: Godsmith/adventofcode2017
""".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'])
コード例 #15
0
    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())
コード例 #16
0
        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)))
コード例 #17
0
ファイル: day25.py プロジェクト: Godsmith/adventofcode2017
        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())
コード例 #18
0
    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)