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())
def inp(): return int(aoc_utils.input().read())
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)
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
# 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
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)
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:
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))
#!/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