Exemplo n.º 1
0
import aoc
from functools import reduce

x = y = aim = 0
for cmd, n in aoc.read():
    match cmd:
        case "forward":
            x += n
            y += aim * n
        case "down":
            aim += n
        case "up":
            aim -= n

print("Part One", x * aim)
print("Part Two", x * y)

inp = aoc.read()


def process(state, command):
    x, y, aim = state
    match command:
        case "forward", arg:
            return [x+arg, y+arg*aim, aim]
        case "up", arg:
            return [x, y, aim-arg]
        case "down", arg:
            return [x, y, aim+arg]
        case _:
            raise Exception(str(command))
Exemplo n.º 2
0
from statistics import median, mean

import aoc

data = aoc.read("input.txt", sep=",", cast_as=int)
m = median(data)
fuel = sum(abs(x - m) for x in data)

print(f"Part 1 - total fuel:", int(fuel))


def triangle_fuel(x, m):
    t = -1 if x < m else 1
    return 0.5 * ((x - m) * (x - m + t))


min = None
for i in range(len(data)):
    fuel = sum(triangle_fuel(x, i) for x in data)
    if min is None or min > fuel:
        min = fuel

print(f"Part 2 - total fuel:", int(min))
Exemplo n.º 3
0
import re
from collections import namedtuple

import aoc

Point = namedtuple("Point", ["x", "y"])

numbers, *cards = aoc.read(path="input.txt", sep="\n\n", cast_as=str)
numbers = [int(n) for n in numbers.split(",")]

N = 5  # Bingo card length
PATTERN_NUM = r"[0-9]+"


def x(i, n=N):
    return i - ((i // n) * n)


def y(i, n=N):
    return i // n


class Card:

    ALL = set(range(N))

    def __init__(self, data):
        ns = re.findall(PATTERN_NUM, data)
        self.data = {int(v): Point(x(i), y(i)) for i, v in enumerate(ns)}
        self.complete = False
Exemplo n.º 4
0
from typing import List, Tuple

import aoc

data = aoc.read(path="input.txt", cast_as=str)

N = len(data[0])
mapper = str.maketrans("01", "10")


def dec(bin: str) -> int:
    return int(bin, 2)


def most_common_bit(l: List[str]) -> str:
    n = len(l)
    ones = len([i for i in l if i == "1"])
    return "1" if ones >= n / 2 else "0"


def gamma(data):

    bits = ""
    for i in range(N):
        bit = most_common_bit([s[i] for s in data])
        bits += bit

    return bits


def epsilon(gamma):
Exemplo n.º 5
0
import aoc


l = aoc.read()

def count(l):
    return sum(b > a for a, b in zip(l, l[1:]))

print(count(l))

# Window of width 3
w = [sum(xs) for xs in zip(l, l[1:], l[2:])]

print(count(w))

Exemplo n.º 6
0
import aoc


def pairwise(s):
    """Not on python 3.10."""
    while True:
        try:
            a, b, *tail = s
        except ValueError:
            return
        yield a + b
        s = [b] + tail


polymer, _, *rules = aoc.read("input.txt", cast_as=str, sep="\n")
final = polymer[-1]  # To add the last letter into the counts at the end
rules = dict(pair.split(" -> ") for pair in rules)

# Initialise
poly = Counter(pairwise(polymer))

# Iterate simultaneously
for _ in range(40):
    new = defaultdict(int)
    for pair in list(poly):
        n = poly[pair]
        insertion = rules[pair]
        new[pair[0] + insertion] += n
        new[insertion + pair[1]] += n
    poly = new
Exemplo n.º 7
0
from aoc import Point, read

from functools import reduce

data = read("input.txt", cast_as=str, sep="\n")
DELIM = data.index("")

points = [Point(*map(int, p.split(","))) for p in data[:DELIM]]
folds = [f.replace("fold along ", "") for f in data[(DELIM + 1):]]


def make_fold(points, fold):
    axis, pos = fold.split("=")
    pos = int(pos)

    for p in points:
        px = (2 * pos - p.x) if (axis == "x") and (p.x > pos) else p.x
        py = (2 * pos - p.y) if (axis == "y") and (p.y > pos) else p.y
        yield Point(px, py)


def printer(points):
    for y in range(10):
        ans = ""
        for x in range(60):
            ans += "#" if Point(x, y) in points else "."
        print(ans)


printer(set(reduce(make_fold, folds, points)))
Exemplo n.º 8
0
import aoc
import more_itertools

inp = aoc.read()[0]
c1 = sum(a < b for a, b in zip(inp, inp[1:]))
print("Part One", c1)

c2 = sum(a < b for a, b in zip(inp, inp[3:]))
c22 = sum(
    sum(inp[i:i + 3]) < sum(inp[i + 1:i + 4]) for i in range(0,
                                                             len(inp) - 3))
c23 = sum(w[0] < w[-1] for w in more_itertools.windowed(inp, 4))
c24 = len([1 for a, b in zip(inp, inp[3:]) if a < b])

print("Part Two", c2, c22, c23, c24)
Exemplo n.º 9
0
from itertools import chain, product
from typing import List

from aoc import Point, read

data = read("input.txt", sep="\n\n", cast_as=str).pop()
N = data.index("\n")
data = data.replace("\n", "")

ADJ = {-1, 0, 1}
ADJ = [v for v in product(ADJ, ADJ) if v != (0, 0)]
ENOUGH_ENERGY = 9


def print_octos(octopodes):
    Y = 1
    for p, e in octopodes.items():
        if p.y == Y:
            print("\n", end="")
            Y += 1
        print(e if e <= ENOUGH_ENERGY else "x", end="")
    print("\n")


def neighbours(p: Point) -> List[Point]:
    return [Point(p.x + dx, p.y + dy) for dx, dy in ADJ]


def count_flashes(octopodes) -> int:
    return list(octopodes.values()).count(0)
Exemplo n.º 10
0
from collections import defaultdict

import aoc

START = "start"
END = "end"

data = aoc.read("input.txt", sep="\n", cast_as=str)

nodes = defaultdict(set)
for edge in data:
    a, b = edge.split("-")
    nodes[a].add(b) if b != START else None
    nodes[b].add(a) if a != START else None
nodes.pop(END)


def traverse():
    explore = [(p, {START, p}) for p in nodes[START]]
    paths = 0

    while explore:
        head, visited = explore.pop()
        neighbours = nodes[head]
        for node in neighbours:
            if node == END:
                paths += 1
            elif node.islower() and (node in visited):
                paths += 0
            else:
                v = visited.copy()
Exemplo n.º 11
0
    assert eval(str(Node(in_).reduce())) == eval(out_)
    print("pass")


# check([[[[[9, 8], 1], 2], 3], 4], "[[[[0,9],2],3],4]")
# check([7, [6, [5, [4, [3, 2]]]]], "[7,[6,[5,[7,0]]]]")
# check([[6, [5, [4, [3, 2]]]], 1], "[[6,[5,[7,0]]],3]")
# check([[3, [2, [1, [7, 3]]]], [6, [5, [4, [3, 2]]]]], "[[3,[2,[8,0]]],[9,[5,[7,0]]]]")

# check(
#     [[[[[4, 3], 4], 4], [7, [[8, 4], 9]]], [1, 1]], "[[[[0,7],4],[[7,8],[6,0]]],[8,1]]"
# )

import aoc

numbers = [Node(eval(n)) for n in aoc.read("input.txt", cast_as=str, sep="\n")]

acc, *numbers = numbers

for n in numbers:
    acc = acc + n
    acc.reduce()


def magnitude(node):
    while True:
        if isinstance(node.l, int) and isinstance(node.r, int):
            return (3 * node.l) + (2 * node.r)

        if isinstance(node.l, Node):
            node.l = magnitude(node.l)