Exemplo n.º 1
0
def part2(seed=puzzle_input(22), bursts=10000000):
    INFECT_COUNT = 0

    grid = {(y, x): 'C' if cell_status == '.' else 'I'
            for y, row in enumerate(seed) for x, cell_status in enumerate(row)}
    map_height = max(k[0] for k in grid) + 1
    map_width = max(k[1] for k in grid) + 1
    position = (map_height // 2, map_width // 2)  # row, Col

    current_direction = 1  # UP

    def current_node():
        return grid.setdefault(position, 'C')

    for _ in range(bursts):

        if current_node() == 'C':
            grid[position] = 'W'
            current_direction = (current_direction - 1) % 4
        elif current_node() == 'W':
            grid[position] = 'I'
            INFECT_COUNT += 1
        elif current_node() == 'I':
            grid[position] = 'F'
            current_direction = (current_direction + 1) % 4
        elif current_node() == 'F':
            grid[position] = 'C'
            current_direction = (current_direction + 2) % 4
        position = DIRECTIONS[current_direction](*position)
    return INFECT_COUNT
Exemplo n.º 2
0
def parse_input():
    translations = {}
    for line in puzzle_input(21):
        before, after = line.split(" => ")
        translations[before] = Grid(after)

    return translations
Exemplo n.º 3
0
def part1(seed=puzzle_input(22), bursts=10000):
    # count the number of times we turn a node from CLEAN to INFECTED
    INFECT_COUNT = 0

    # we use a dict to avoid extending our grid when position goes out of bounds
    grid = {(y, x): cell_status
            for y, row in enumerate(seed) for x, cell_status in enumerate(row)}
    map_height = max(k[0] for k in grid) + 1
    map_width = max(k[1] for k in grid) + 1
    position = (map_height // 2, map_width // 2)  # row, Col

    # use for turning left/right from our direction
    current_direction = 1  # UP

    def current_node():
        return grid.setdefault(position, CLEAN)

    for _ in range(bursts):
        if current_node() == INFECTED:
            current_direction = (current_direction + 1) % 4
            grid[position] = CLEAN
        else:
            current_direction = (current_direction - 1) % 4
            grid[position] = INFECTED
            INFECT_COUNT += 1
        position = DIRECTIONS[current_direction](*position)
    return INFECT_COUNT
Exemplo n.º 4
0
from common import puzzle_input, parse_int
from collections import defaultdict

PUZZLE_INPUT = puzzle_input(20)

def add(xs, ys): return tuple(x + y for x, y in zip(xs, ys))

class Particle:
    next_id = 0

    def __init__(self, position, velocity, acceleration):
        self.id = self.next_id
        Particle.next_id += 1

        assert len(position) == 3
        self.position = position
        assert len(velocity) == 3
        self.velocity = velocity
        assert len(acceleration) == 3
        self.acceleration = acceleration

    def __repr__(self):
        return f"Particle({self.position}, {self.velocity}, {self.acceleration})"

    @classmethod
    def from_input(cls, line):
        """Create new Particle object from puzzle input"""
        *data, _trash = line.split('>')
        data = [parse_int(triplet) for triplet in data]
        return cls(*data)
Exemplo n.º 5
0
def part2(data=puzzle_input(4)):
    def valid(wordlist):
        wordlist = [cat(sorted(word)) for word in wordlist]
        return len(wordlist) == len(set(wordlist))
    return sum(map(valid, [line.split() for line in data]))
Exemplo n.º 6
0
def part1(data=puzzle_input(4)):
    def valid(wordlist):
        return len(wordlist) == len(set(wordlist))
    return sum(map(valid, [line.split() for line in data]))
Exemplo n.º 7
0
from itertools import tee
from common import puzzle_input

PUZZLE_INPUT = puzzle_input(1)[0]


def circular_chunk(it: str):
    """
    yields it[0], it[1]: it[1], it[2]:, it[2], it[3]... it[n-2], it[n-1]
    as well as it[n-1], it[0]
    """
    a, b = tee(it)
    next(b)
    yield from zip(a, b)
    yield it[-1], it[0]


def halfway_chunk(it: str):
    """
    yields pairs of elements opposite from eachother
    """
    n = len(it)
    distance = n // 2
    for i in range(n):
        j = (i + distance) % n
        yield it[i], it[j]


def part1(data):
    chunks = circular_chunk(data)
    only_same = (int(a) for a, b in chunks if a == b)

def parse_line(line):
    if '->' in line:
        first, second = line.split('->')
        second = second.strip().split(', ')
    else:
        first = line
        second = []
    name, weight = first.strip().split()
    weight = int(weight.strip('()'))

    return Node(name, weight), second


PUZZLE_INPUT = [parse_line(line) for line in puzzle_input(7)]


def part1(data=PUZZLE_INPUT):
    has_children = set()
    is_child = set()

    for prog, children in data:
        if children:
            is_child = is_child.union(set(children))
            has_children.add(prog)

    for prog, _ in data:
        if (prog in has_children) and (prog.name not in is_child):
            return prog
def parse_input(data=puzzle_input(12)):
    for line in data:
        left, right = line.split(' <-> ')
        right = set(map(int, right.split(',')))
        yield int(left), right
Exemplo n.º 10
0
from common import puzzle_input, parse_int

PUZZLE_INPUT = dict(map(parse_int, puzzle_input(13)))


def scanner_on_top(rnge, turn=0):
    if rnge == 0:
        return False
    trip_time = (rnge - 1) * 2
    return turn % trip_time == 0


def part1(data=PUZZLE_INPUT):
    return sum(depth * range for depth, range in data.items()
               if scanner_on_top(range, depth))


def part2(data=PUZZLE_INPUT):
    delay = 1
    while True:
        if not any(
                scanner_on_top(rnge, depth + delay)
                for depth, rnge in data.items()):
            return delay
        else:
            delay += 1


if __name__ == '__main__':
    example = {0: 3, 1: 2, 4: 4, 6: 4}
    assert part1(example) == 24
Exemplo n.º 11
0
from common import puzzle_input, parse_int

PUZZLE_INPUT = puzzle_input(16)[0].split(',')


def cat(args):
    return ''.join(args)


def part1(instructions=PUZZLE_INPUT, progs=None):
    if progs is None:
        progs = list('abcdefghijklmnop')

    for line in instructions:
        cmd = line.startswith
        if cmd('x'):
            a, b = parse_int(line)
            progs[b], progs[a] = progs[a], progs[b]
        elif cmd('p'):
            a, b = line[1], line[3]
            ai, bi = progs.index(a), progs.index(b)
            progs[ai], progs[bi] = progs[bi], progs[ai]
        elif cmd('s'):
            n = int(line[1:])
            progs = progs[-n:] + progs[:-n]

    return ''.join(progs)


def part2(instructions=PUZZLE_INPUT):
    count = 0
Exemplo n.º 12
0
# https://adventofcode.com/2018/day/1
from itertools import accumulate, cycle

from common import puzzle_input

PUZZLE_INPUT = [int(i) for i in puzzle_input(1)]


def seen_twice(iterable):
    seen = set()
    for element in iterable:
        if element in seen:
            yield element
        seen.add(element)


def part1(data=PUZZLE_INPUT):
    return sum(data)


def part2(data=PUZZLE_INPUT):
    return next(seen_twice(accumulate(cycle(data))))


if __name__ == "__main__":
    print("Part 1 result:", part1())
    print("Part 2 result:", part2())
Exemplo n.º 13
0
from common import puzzle_input

PUZZLE_INPUT = list(puzzle_input(5)[0])


def part1(data=PUZZLE_INPUT[:]):

    while True:
        for i, char in enumerate(data[:-1]):
            if char.swapcase() == data[i + 1]:  # we have a pair
                data.pop(i + 1)
                data.pop(i)
                break  # restart for loop
        else:
            return len(data)


def part2(data=PUZZLE_INPUT):
    """Like part1, but 26 times"""
    from string import ascii_lowercase

    results = []
    for letter in ascii_lowercase:
        print('calculating letter ', letter)
        letter_removed = [char for char in data if char.lower() != letter]
        results.append(part1(data=letter_removed))

    return min(results)


if __name__ == '__main__':
Exemplo n.º 14
0
        if parse_int(action):
            guard_id = parse_int(action)[0]
        elif action.endswith("falls asleep"):
            nap_start = timestamp
        elif action.endswith("wakes up"):
            duration = timestamp - nap_start
            # drop last one, which is when they wake up
            minutes = [ts.minute for ts in duration.range("minutes")][:-1]

            guard_log = guard_nap_minutes.setdefault(guard_id, [])
            guard_log.extend(minutes)

    return guard_nap_minutes


PUZZLE_INPUT = prep_input(puzzle_input(4))


def part1(data=PUZZLE_INPUT):
    # find nappiest guard, guess which minute he is asleep
    guard, naps = max(data.items(), key=lambda tup: len(tup[1]))
    most_common_minute, count = Counter(naps).most_common(1)[0]
    return guard * most_common_minute

    # find most common minute asleep among that guards naps
    # multiple the minute and guard id together


def part2(data=PUZZLE_INPUT):
    # find which guard naps most regularly
from itertools import combinations

from common import puzzle_input

PUZZLE_INPUT = [[int(num) for num in row.split()] for row in puzzle_input(2)]


def find_quotient(nums: list):
    for pair in combinations(sorted(nums, reverse=True), 2):
        result, remainder = divmod(*pair)
        if remainder == 0:
            return result


def part1(data=PUZZLE_INPUT):
    result = sum(max(row) - min(row) for row in data)
    return result


def part2(data=PUZZLE_INPUT):
    result = sum(find_quotient(row) for row in data)
    return result


if __name__ == '__main__':
    print('Part one result:', part1())
    print('Part 2:', part2())
Exemplo n.º 16
0
"https://adventofcode.com/2018/day/3"

from common import puzzle_input, parse_int

from collections import Counter

PUZZLE_INPUT = [parse_int(line) for line in puzzle_input(3)]


def square_inch_ids(x_offset, y_offset, width, height):
    """
    generates a series representing the ids each
    square inch of fabric used for this claim
    """
    start = y_offset * 1000 + x_offset
    for i in range(width):
        for j in range(height):
            yield start + i + (j * 1000)


def part1(data=PUZZLE_INPUT):
    square_count = Counter()

    for _id, *square in PUZZLE_INPUT:
        square_count.update(square_inch_ids(*square))

    return sum(count > 1 for count in square_count.values())


def part2(data=PUZZLE_INPUT):
    claim_ids = set()