Esempio n. 1
0
def part_1(raw: str, ints: list[int], strs: list[str]):
    match strs:
        case [lengths, nums]:
            nums = aoc.ints(nums)
        case [lengths]:
            nums = list(range(256))

    lengths = aoc.ints(lengths)

    pos = 0
    skip = 0
    for length in lengths:
        indices = list(range(pos, pos + length))

        temp = []
        for i in indices:
            temp.append(nums[i % len(nums)])

        for i in indices:
            nums[i % len(nums)] = temp.pop()

        pos += (length + skip) % len(nums)
        skip += 1

    return nums[0] * nums[1]
Esempio n. 2
0
def part_2(raw: str, ints: list[int], strs: list[str]):
    _, _, x_range, y_range = raw.split()
    x0, x1 = aoc.ints(x_range.split("=")[1].strip(",").split(".."))
    y0, y1 = sorted(aoc.ints(y_range.split("=")[1].split("..")))

    cords = []

    total = 0
    for vx0 in range(1, x1 + 1):
        for vy0 in range(-max(abs(y1), abs(y0)), max(abs(y1), abs(y0)) + 1):
            t = 1

            y_max = 0
            while x(vx0, t) <= x1:
                y_max = max(y(vy0, t), y_max)

                if y0 <= y(vy0, t) <= y1 and x0 <= x(vx0, t) <= x1:
                    cords.append((vx0, vy0))
                    total += 1
                    break

                if vx(vx0, t) == 0 and vy(vy0, t) < 0 and y(vy0, t) < min(y1, y0):
                    break

                t += 1

    return total
Esempio n. 3
0
def part_2(raw: str, ints: list[int], strs: list[str]):
    t = 0

    for line in strs:
        l, w, h = aoc.ints(line)
        x, y = sorted(aoc.ints(line))[:2]

        a = 2 * x + 2 * y
        b = l * w * h
        t += a + b

    return t
Esempio n. 4
0
def part_2(raw: str, ints: List[int], strs: List[str]):
    banks = aoc.ints(strs[0])

    mem = set(" ".join([str(b) for b in banks]))
    steps = 0
    seen = ""
    while True:
        s = banks.index(max(banks))

        banks[s], cash = 0, banks[s]
        for i in itertools.cycle(range(len(banks))):
            if cash == 0:
                break

            i += s + 1
            i = i % len(banks)
            banks[i] += 1
            cash -= 1

        steps += 1

        banks_str = " ".join([str(b) for b in banks])
        if banks_str in mem:
            if not seen:
                seen = banks_str
                steps = 0
            elif banks_str == seen:
                return steps

        if not seen:
            mem.add(banks_str)
Esempio n. 5
0
def part_2(raw: str, ints: list[int], strs: list[str]):
    grid = aoc.Grid.of(Light, height=1000, width=1000)

    for line in strs:
        line, b = line.split(" through ")
        inst, a = line.rsplit(" ", 1)

        subgrid = grid.subgrid(aoc.ints(a.split(",")), aoc.ints(b.split(",")))

        match inst:
            case "turn on":
                subgrid.for_each(Light.turn_on_2)
            case "turn off":
                subgrid.for_each(Light.turn_off_2)
            case "toggle":
                subgrid.for_each(Light.toggle_2)


    return sum([l.brightness for l in grid.values()])
Esempio n. 6
0
def part_1(raw: str, ints: list[int], strs: list[str]):
    bings = aoc.ints(strs[0])

    boards = [BingoBoard.populate(s) for s in raw.split("\n\n")[1:]]
    for b, bing in enumerate(bings, 1):
        for board in boards:
            board.bing(bing)

            if board.winner():
                return sum(b.value for b in board.unbinged()) * bing
Esempio n. 7
0
def part_2(raw: str, ints: List[int], strs: List[str]):
    s = 0

    for line in strs:
        nums = aoc.ints(line)
        for a, b in itertools.combinations(nums, 2):
            a , b =  (a, b) if a > b else (b , a)
            s += int(a / b) if a % b == 0 else 0

    return s
Esempio n. 8
0
def part_1(raw: str, ints: list[int], strs: list[str]):
    t = 0

    for l in strs:
        l, w, h = aoc.ints(l)
        a = l * w
        b = w * h
        c = h * l

        t += 2 * a + 2 * b + 2 * c + min(a, b, c)

    return t
Esempio n. 9
0
def part_1(raw: str, ints: list[int], strs: list[str]):
    _, _, x_range, y_range = raw.split()
    x0, x1 = aoc.ints(x_range.split("=")[1].strip(",").split(".."))
    y0, y1 = sorted(aoc.ints(y_range.split("=")[1].split("..")))

    highest_y = float("-inf")
    for vx0 in range(1, x1):
        for vy0 in range(-max(abs(y1), abs(y0)), max(abs(y1), abs(y0))):
            t = 1

            y_max = 0
            while x(vx0, t) < x1:
                y_max = max(y(vy0, t), y_max)

                if y0 <= y(vy0, t) <= y1 and x0 <= x(vx0, t) <= x1:
                    highest_y = max(y_max, highest_y)
                    break

                if vx(vx0, t) == 0 and vy(vy0, t) < 0 and y(vy0, t) < y1:
                    break

                t += 1

    return highest_y
Esempio n. 10
0
def part_2(raw: str, ints: list[int], strs: list[str]):
    points = defaultdict(bool)
    inst, folds = raw.split("\n\n")

    width = 0
    height = 0

    for line in inst.splitlines():
        x, y = aoc.ints(line.split(","))
        points[x, y] = True
        width = max(x, width)
        height = max(y, height)

    width = width + 1
    height = height + 1

    for f in folds.splitlines():
        axis, n = f.split()[-1].split("=")
        num = int(n)
        if axis == "y":
            for y in range(num + 1, height):
                for x in range(width):
                    d = y - num
                    merge = (x, y)
                    dest = (x, num - d)
                    points[dest] |= points[merge]

            height = num

        elif axis == "x":
            for x in range(num + 1, width):
                for y in range(height):
                    d = x - num
                    merge = (x, y)
                    points[(num - d, y)] |= points[merge]

            width = num

    hash_and_dots: list[str] = []

    for y in range(height):
        row = ''
        for x in range(width):
            row += '#' if points[(x, y)] else "."
        hash_and_dots.append(row)

    print('\n'.join(hash_and_dots))
    return "O"
Esempio n. 11
0
def part_1(raw: str, ints: list[int], strs: list[str]):
    points = defaultdict(bool)
    inst, folds = raw.split("\n\n")

    width = 0
    height = 0

    for line in inst.splitlines():
        x, y = aoc.ints(line.split(","))
        points[(x, y)] = True
        width = max(x, width)
        height = max(y, height)

    width = width + 1
    height = height + 1

    for f in folds.splitlines():
        axis, n = f.split()[-1].split("=")
        num = int(n)
        if axis == "y":
            for y in range(num + 1, height):
                for x in range(width):
                    points[(x, 2 * num - y)] |= points[(x, y)]

            height = num

        elif axis == "x":
            for x in range(num + 1, width):
                for y in range(height):
                    points[(2 * num - x, y)] |= points[(x, y)]

            width = num

        break

    total = 0
    for y in range(height):
        for x in range(width):
            total += points[(x, y)]
    return total
Esempio n. 12
0
def part_2(raw: str, ints: list[int], strs: list[str]):
    bings = aoc.ints(strs[0])

    boards = [BingoBoard.populate(s) for s in raw.split("\n\n")[1:]]

    winners: list[int] = []

    for bing in bings:

        for i, board in enumerate(boards, 1):
            board.bing(bing)

            # if i == 2:
            #     print(f"Bing: {bing}")
            #     board.display()

            if i not in winners and board.winner():
                score = sum(b.value for b in board.unbinged()) * bing
                winners.append(i)
                print(f"Board {i} score: {score}")
                print("--------------------")
                board.display()

    return score
Esempio n. 13
0
def part_1(raw: str, ints: List[int], strs: List[str]):
    chk = 0
    for l in strs:
        nums = aoc.ints(l)
        chk += max(nums) - min(nums)
    return chk