コード例 #1
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_two(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    seat_ids = sorted([get_seat_id(line) for line in lines])
    missing = seat_ids[0]
    for s in seat_ids:
        missing ^= s
    return missing
コード例 #2
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_one(filename: str) -> int:
    public_keys = read_integers(get_path(__file__, filename))
    pub_key1, pub_key2 = public_keys[0], public_keys[1]
    loop1, loop2 = get_loop_size(pub_key1), get_loop_size(pub_key2)
    encryption_key = transform(pub_key1, loop2)
    assert (encryption_key == transform(pub_key2, loop1))
    return encryption_key
コード例 #3
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_two(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    area = [[c for c in line] for line in lines]
    h, w = len(area), len(area[0])
    old_area = None

    while area != old_area:
        old_area = [[area[r][c] for c in range(w)] for r in range(h)]
        for r in range(h):
            for c in range(w):
                if old_area[r][c] != PATH:
                    
                    occupied = 0
                    for dr, dc in NEIGHBOURS:
                        nr, nc = r + dr, c + dc
                        # keep moving in same direction till empty or filled seat
                        while 0 <= nr < h and 0 <= nc < w and old_area[nr][nc] != EMPTY_SEAT:
                            if old_area[nr][nc] == FILLED_SEAT:
                                occupied += 1
                                break
                            nr, nc = nr + dr, nc + dc

                    if occupied == 0:
                        area[r][c] = FILLED_SEAT
                    elif occupied >= 5:
                        area[r][c] = EMPTY_SEAT
    
    return sum([x.count(FILLED_SEAT) for x in area])
コード例 #4
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_one(filename: str) -> int:
    direction = 90
    x, y = 0, 0
    lines = read_lines(get_path(__file__, filename))
    for l in lines:
        d, v = l[0], int(l[1:])

        if d == "R":
            direction = (direction + v) % 360

        if d == "L":
            direction = (direction - v) % 360

        if d == "N":
            y += v

        if d == "E":
            x += v

        if d == "S":
            y -= v

        if d == "W":
            x -= v

        if d == "F":
            y += math.cos(math.radians(direction)) * v
            x += math.sin(math.radians(direction)) * v

    return abs(x) + abs(y)
コード例 #5
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_two(filename: str) -> int:
    wx, wy = 10, 1
    sx, sy = 0, 0
    lines = read_lines(get_path(__file__, filename))
    for l in lines:
        d, v = l[0], int(l[1:])

        if d == "R":
            wx, wy = rotate_coords(wx, wy, v)

        if d == "L":
            wx, wy = rotate_coords(wx, wy, 360 - v)

        if d == "N":
            wy += v

        if d == "E":
            wx += v

        if d == "S":
            wy -= v

        if d == "W":
            wx -= v

        if d == "F":
            sx += wx * v
            sy += wy * v

    return abs(sx) + abs(sy)
コード例 #6
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_one(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    return sum([
        int(min_c) <= p.count(l) <= int(max_c) for w in lines
        for min_c, max_c, l, p in (
            re.search(r'(\d+)-(\d+) ([a-z]): ([a-z]+)', w).groups(), )
    ])
コード例 #7
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_two(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    memory = {}

    for line in lines:
        splitted = line.split("=")
        key, val = splitted[0].strip(), splitted[1].strip()

        if key == "mask":
            mask = val
        else:
            address = int(re.search(r'mem\[(\d+)]', key).groups()[0])
            address_base = list('{:036b}'.format(address))
            floating = 0
            # replace with 1's, mark x's with {} for formatting
            for i in range(BITS):
                if mask[i] == "X":
                    address_base[i] = "{}"
                    floating += 1
                elif mask[i] == "1":
                    address_base[i] = "1"
            format_address = "".join(address_base)
            if floating > 0:
                bin_format = "0{}b".format(floating)
                # insert each binary number up to 2**floating into positions of X's
                for i in range(2**floating):
                    mem_address = format_address.format(*format(i, bin_format))
                    memory[int(mem_address, 2)] = int(val)
            else:
                memory[int("".join(format_address), 2)] = int(val)

    return sum(memory.values())
コード例 #8
0
def part_two(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    recipes = [Recipe(line) for line in lines]
    matched = get_matching(recipes)

    ing_list = [matched[k] for k in sorted(matched)]

    return ",".join(ing_list)
コード例 #9
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_two(filename: str) -> int:
    ints = read_integers(get_path(__file__, filename))
    # use twosum solution from p1 to reduce time complexity from
    # O(n^3) to O(n^2)
    for i, n in enumerate(ints):
        multiplier = two_sum(ints[i + 1:], 2020 - n)
        if multiplier != -1:
            return n * multiplier
    return -1
コード例 #10
0
def part_two(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    trees = [
        get_trees(1, 1, lines),
        get_trees(1, 3, lines),
        get_trees(1, 5, lines),
        get_trees(1, 7, lines),
        get_trees(2, 1, lines)
    ]
    return reduce((lambda x, y: x * y), trees)
コード例 #11
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_one(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    earliest, shortest_wait, bus_id = int(lines[0]), float('inf'), None

    for b in [int(x) for x in lines[1].split(',') if x.isnumeric()]:
        wait = (((earliest // b) * b) + b) - earliest
        if wait < shortest_wait:
            shortest_wait, bus_id = wait, b

    return shortest_wait * bus_id if shortest_wait else -1
コード例 #12
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_one(filename: str) -> int:
    ints = read_integers(get_path(__file__, filename))
    ints.sort()
    ones, threes, v = 0, 0, 0

    for x in ints:
        threes += (x - v == 3)
        ones += (x - v == 1)
        v = x

    return ones * (threes + 1)
コード例 #13
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_one(filename: str) -> int:
    lines = read_raw(get_path(__file__, filename))
    pports = lines.split("\n\n")
    valid_pports = []
    for p in pports:
        valid_fields = 0
        for f in p.replace("\n", " ").split():
            k, v = f.split(":")
            valid_fields += k in checks.keys()
        if valid_fields >= 7:
            valid_pports.append(p)
    return len(valid_pports)
コード例 #14
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_two(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    running_product, earliest_bus = 1, 0

    # uses chinese remainder theorem
    for (index, bus) in enumerate(lines[1].split(",")):
        if bus != "x":
            while ((earliest_bus + index) % int(bus)) != 0:
                earliest_bus += running_product
            running_product *= int(bus)

    return earliest_bus
コード例 #15
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def parse_input(filename: str) -> dict:
    inp = read_raw(get_path(__file__, filename))
    splitted = inp.split("\n\n")
    tiles = []
    for tile in splitted:
        lines = tile.split("\n")
        id = int(lines[0].split(" ")[1].rstrip(":"))
        tile = Tile(id, [[x for x in l]
                         for l in lines[1:]])
        tile.calc_versions()
        tiles.append(tile)
    return tiles
コード例 #16
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_two(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))

    board = Board_2(lines)

    for i in range(6):

        # print("ROUND: {}".format(i))
        board.cycle()
        # board.print()

    return board.count_alive()
コード例 #17
0
def part_one(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    recipes = [Recipe(line) for line in lines]
    matched = get_matching(recipes)

    res = 0
    matched_ing = matched.values()
    for arr in [r.ingredients for r in recipes]:
        for i in arr:
            if i not in matched_ing:
                res += 1

    return res
コード例 #18
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def process_bags(filename) -> dict:
    lines = read_lines(get_path(__file__, filename))
    bags = {}
    for line in lines:
        outer_bag, inner_bags = line.split("contain")
        outer_bag = outer_bag.strip().rstrip("s")
        bags[outer_bag] = []
        if inner_bags != " no other bags.":
            for bag in inner_bags.split(","):
                r = re.search(r'(\d+) (\S+.*)', bag.replace(".", ""))
                if r:
                    num, bag_name = r.groups()
                    bags[outer_bag].append((int(num), bag_name.rstrip("s")))
    return bags
コード例 #19
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_two_2(filename: str) -> int:
    ints = read_integers(get_path(__file__, filename))
    ints_set = set(ints)
    ints.sort()
    ways = [0] * (max(ints) + 1)

    for x in [1, 2, 3]:
        ways[x] = int(x in ints)

    for i in range(2, max(ints) + 1):
        if i in ints_set:
            ways[i] += ways[i - 1] + ways[i - 2] + ways[i - 3]

    return ways[-1]
コード例 #20
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_two_1(filename: str) -> int:
    ints = read_integers(get_path(__file__, filename))
    ints_set = set(ints)
    cache = [-1] * max(ints)

    def number_ways(v):
        if v not in ints_set:
            return 0
        if v == max(ints):
            return 1

        if cache[v] == -1:
            cache[v] = sum([number_ways(v + x) for x in range(1, 4)])

        return cache[v]

    return sum([number_ways(x) for x in range(1, 4)])
コード例 #21
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_one(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    memory = {}

    for line in lines:
        splitted = line.split("=")
        key, val = splitted[0].strip(), splitted[1].strip()

        if key == "mask":
            mask = val
        else:
            address = int(re.search(r'mem\[(\d+)]', key).groups()[0])
            val = list('{:036b}'.format(int(val)))
            for idx, c in enumerate(mask):
                val[idx] = c if c != "X" else val[idx]
            memory[address] = int("".join(val), 2)

    return sum(memory.values())
コード例 #22
0
def part_two(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))

    for i, line in enumerate(lines):
        code, value = line.split(" ")

        if code == "nop":
            line_copy = lines[:]
            line_copy[i] = "{} {}".format("jmp", value)
            completed, acc = run_code(line_copy)
            if completed:
                return acc

        elif code == "jmp":
            line_copy = lines[:]
            line_copy[i] = "{} {}".format("nop", value)
            completed, acc = run_code(line_copy)
            if completed:
                return acc

    return -1
コード例 #23
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_one(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    area = [[c for c in line] for line in lines]
    h, w = len(area), len(area[0])
    old_area = None

    while area != old_area:
        old_area = [[area[r][c] for c in range(w)] for r in range(h)]
        for r in range(h):
            for c in range(w):
                if old_area[r][c] != PATH:
                    
                    occupied = 0
                    for dr, dc in NEIGHBOURS:
                        nr, nc = r + dr, c + dc
                        if 0 <= nr < h and 0 <= nc < w and old_area[nr][nc] == FILLED_SEAT:
                            occupied += 1
                    if occupied == 0:
                        area[r][c] = FILLED_SEAT
                    elif occupied >= 4:
                        area[r][c] = EMPTY_SEAT

    return sum([x.count(FILLED_SEAT) for x in area])
コード例 #24
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def parse_input(filename):
    lines = read_lines(get_path(__file__, filename))
    player1 = deque([int(l) for l in lines[lines.index(
        "Player 1:") + 1:lines.index("Player 2:") - 1]])
    player2 = deque([int(l) for l in lines[lines.index("Player 2:") + 1:]])
    return player1, player2
コード例 #25
0
def part_one(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    return get_trees(1, 3, lines)
コード例 #26
0
def part_one(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    black = get_tiles(lines)
    return len(black)
コード例 #27
0
def part_two(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    black = get_tiles(lines)
    black = game_of_life(black, 100)
    return len(black)
コード例 #28
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_one(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    return max([get_seat_id(line) for line in lines])
コード例 #29
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def part_two(filename: str) -> int:
    lines = read_lines(get_path(__file__, filename))
    return sum([(p[int(pos1) - 1] == l) ^ (p[int(pos2) - 1] == l)
                for w in lines for pos1, pos2, l, p in (
                    re.search(r'(\d+)-(\d+) ([a-z]): ([a-z]+)', w).groups(), )
                ])
コード例 #30
0
ファイル: main.py プロジェクト: jcockbain/advent-of-code-2020
def path(filename: str):
    return get_path(__file__, filename)