Exemplo n.º 1
0
            else 0
        )

    def evaluate(self) -> int:
        """evaluate the expression represented by the BITS transmission"""
        if self.type == 0:
            return sum(p.evaluate() for p in self.subpackets)
        elif self.type == 1:
            return math.prod(p.evaluate() for p in self.subpackets)
        elif self.type == 2:
            return min(p.evaluate() for p in self.subpackets)
        elif self.type == 3:
            return max(p.evaluate() for p in self.subpackets)
        elif self.type == 4:
            return self.value
        elif self.type == 5:
            return int(self.subpackets[0].evaluate() > self.subpackets[1].evaluate())
        elif self.type == 6:
            return int(self.subpackets[0].evaluate() < self.subpackets[1].evaluate())
        elif self.type == 7:
            return int(self.subpackets[0].evaluate() == self.subpackets[1].evaluate())


if __name__ == "__main__":
    with aoc_utils.input() as f:
        s = f.read().strip()

    root = Packet(hex2bin(s))
    print(root.version_sum())
    print(root.evaluate())
Exemplo n.º 2
0
def inp():
    return int(aoc_utils.input().read())
Exemplo n.º 3
0
        return False
    return True


def execute(o, a, b):
    if o == "*":
        return a * b
    elif o == "+":
        return a + b


# samples given on page
# print(evaluate("1 + 2 * 3 + 4  * 5 + 6"))
# print(evaluate("1 + (2 * 3) + (4 * (5 + 6))"))
# print(evaluate("2 * 3 + (4 * 5)"))
# print(evaluate("5 + (8 * 3 + 9 + 3 * 4 * 3)"))
# print(evaluate("5 * 9 * (7 * 3 * 3 + 9 * 3 + (8 + 6 * 4))"))
# print(evaluate("((2 + 4 * 9) * (6 + 9 * 8 + 6) + 6) + 2 + 4 * 2"))

inp = aoc_utils.input().readlines()

s = 0
for line in inp:
    s += evaluate(line)
print(s)

s = 0
for line in inp:
    s += evaluate(line, True)
print(s)
Exemplo n.º 4
0
def intcode(inp, noun, verb):
    xs = list(map(int, inp.split(",")))

    xs[1], xs[2] = noun, verb

    i = 0
    while True:
        if xs[i] == 1:
            xs[xs[i + 3]] = xs[xs[i + 1]] + xs[xs[i + 2]]
            i += 4
        elif xs[i] == 2:
            xs[xs[i + 3]] = xs[xs[i + 1]] * xs[xs[i + 2]]
            i += 4
        elif xs[i] == 99:
            break
    return xs


# should print 3500
# print(intcode("1,9,10,3,2,3,11,0,99,30,40,50"))

# Part 1
print(intcode(aoc_utils.input().read(), 12, 2)[0])

# Part 2
for n, v in itertools.product(range(100), range(100)):
    if intcode(aoc_utils.input().read(), n, v)[0] == 19690720:
        print(100 * n + v)
        break
Exemplo n.º 5
0
# set strip to False to see the grid with borders left in
def render(grid, strip=True):
    lines = []
    for row in grid:
        image_row = (map("".join,
                         strip_borders(tile) if strip else tile)
                     for _, tile in row)
        lines.extend(map(("" if strip else " ").join, zip(*image_row)))

        if not strip:
            lines.append("")
    return lines


if __name__ == "__main__":
    tiles = parse(aoc_utils.input().read())

    corners = [
        tile_id for tile_id in tiles if list(
            adjacent_tiles(tile_id, tiles[tile_id], tiles)).count(False) == 2
    ]
    print(prod(corners))

    # Part 2

    sidelength = int(sqrt(len(tiles)))
    grid = [[None for _ in range(sidelength)] for _ in range(sidelength)]

    for row in range(sidelength):
        if row == 0:
            # fix top-left corner
Exemplo n.º 6
0
def play_game(deck1, deck2, part1, out=False, game_count=1):
    if out:
        print(f"\n=== NEW GAME (GAME {game_count}) ===")

    # set game to None if this is part 1
    # that way it will not recurse
    game = None if part1 else set()
    while deck1 and deck2:
        deck1, deck2, game = combat_round(deck1, deck2, game, out, game_count)

    if game_count == 1:
        if not deck1:
            print(score(deck2))
        else:
            print(score(deck1))

    return 2 if not deck1 else 1


inp = aoc_utils.input().read()

# we must assume that the input always has two players' decks
# although there is no validation that the input is such
deck1, deck2 = parse(inp)
play_game(deck1, deck2, True, False)

# parse it again because the decks will have been overwritten by part 1
deck1, deck2 = parse(inp)
play_game(deck1, deck2, False, False)
Exemplo n.º 7
0
from operator import add
from copy import deepcopy
import itertools
import aoc_utils

dimensions = 4

# use a set instead of a list for O(1) `x in s` lookups
# https://wiki.python.org/moin/TimeComplexity
d = set()

for y, line in enumerate(aoc_utils.input().readlines()):
    for x, col in enumerate(line):
        if col == "#":
            d.add(tuple([x, y] + [0] * (dimensions - 2)))

deltas = set(itertools.product([-1, 0, 1], repeat=dimensions))
deltas.remove(tuple([0] * dimensions))


def cycle():
    data = deepcopy(d)
    changeable = set()
    for point in data:
        changeable.add(point)
        for delta in deltas:
            changeable.add(tuple(map(add, point, delta)))

    for point in changeable:
        neighbours = 0
        for delta in deltas:
Exemplo n.º 8
0
                pass

    for tile, flips in tiles.items():
        adjacent_black_tiles = 0
        for adj_tile in adjacent_tiles(tile):
            if tiles.get(adj_tile, 0) % 2 == 1:
                adjacent_black_tiles += 1

        if flips % 2 == 1:
            if adjacent_black_tiles == 0 or adjacent_black_tiles > 2:
                new_tiles[tile] += 1
        else:
            if adjacent_black_tiles == 2:
                new_tiles[tile] += 1

    return new_tiles


if __name__ == "__main__":

    tiles = defaultdict(int)
    for line in aoc_utils.input().readlines():
        tiles[parse(line.strip())] += 1

    print(count_black_tiles(tiles))

    for _ in range(100):
        tiles = cellular_automata(tiles)

    print(count_black_tiles(tiles))
Exemplo n.º 9
0
#!/usr/bin/python3

from functools import lru_cache
from collections import *
import itertools
import random
import re
import sys
import aoc_utils

rules, ms = aoc_utils.input().read().split("\n\n")

rs = {}
for rule in rules.split("\n"):
    rule = rule.split(": ")
    rs[rule[0]] = rule[1]


@lru_cache()
def eval(s, part2=False):
    groups = []
    for group in s.split(" | "):
        cgroup = ""
        for rule in group.split(" "):
            # hacky way of saying "if it's actually a letter"
            if len(rs[rule]
                   ) == 3 and rs[rule][0] == '"' and rs[rule][2] == '"':
                cgroup += rs[rule][1]
            else:
                if part2 and rule == "8":
                    # could be any non-zero number of 42s, basically