2018: d16: ex1: add solution

This commit is contained in:
Bruno BELANYI 2024-12-30 17:23:48 -05:00
parent d0013a1e17
commit 1aea4b9bcd

110
2018/d16/ex1/ex1.py Executable file
View file

@ -0,0 +1,110 @@
#!/usr/bin/env python
import copy
import enum
import sys
from typing import NamedTuple
class OpCode(enum.StrEnum):
ADDR = "addr"
ADDI = "addi"
MULR = "mulr"
MULI = "muli"
BANR = "banr"
BANI = "bani"
BORR = "borr"
BORI = "bori"
SETR = "setr"
SETI = "seti"
GTIR = "gtir"
GTRI = "gtri"
GTRR = "gtrr"
EQIR = "eqir"
EQRI = "eqri"
EQRR = "eqrr"
def apply(self, registers: list[int], a: int, b: int, c: int) -> list[int]:
registers = copy.deepcopy(registers)
if self == OpCode.ADDR:
registers[c] = registers[a] + registers[b]
if self == OpCode.ADDI:
registers[c] = registers[a] + b
if self == OpCode.MULR:
registers[c] = registers[a] * registers[b]
if self == OpCode.MULI:
registers[c] = registers[a] * b
if self == OpCode.BANR:
registers[c] = registers[a] & registers[b]
if self == OpCode.BANI:
registers[c] = registers[a] & b
if self == OpCode.BORR:
registers[c] = registers[a] | registers[b]
if self == OpCode.BORI:
registers[c] = registers[a] | b
if self == OpCode.SETR:
registers[c] = registers[a]
if self == OpCode.SETI:
registers[c] = a
if self == OpCode.GTIR:
registers[c] = a > registers[b]
if self == OpCode.GTRI:
registers[c] = registers[a] > b
if self == OpCode.GTRR:
registers[c] = registers[a] > registers[b]
if self == OpCode.EQIR:
registers[c] = a == registers[b]
if self == OpCode.EQRI:
registers[c] = registers[a] == b
if self == OpCode.EQRR:
registers[c] = registers[a] == registers[b]
return registers
Instruction = list[int]
class Example(NamedTuple):
before: list[int]
data: Instruction
after: list[int]
def solve(input: str) -> int:
def parse_example(input: list[str]) -> Example:
before = input[0].removeprefix("Before: [").removesuffix("]")
data = input[1]
after = input[2].removeprefix("After: [").removesuffix("]")
return Example(
[int(n) for n in before.split(", ")],
[int(n) for n in data.split()],
[int(n) for n in after.split(", ")],
)
def parse_examples(input: str) -> list[Example]:
return [parse_example(example.splitlines()) for example in input.split("\n\n")]
def parse_data(input: list[str]) -> list[Instruction]:
return [[int(n) for n in line.split()] for line in input]
def parse(input: str) -> tuple[list[Example], list[Instruction]]:
examples, data = input.split("\n\n\n\n")
return parse_examples(examples), parse_data(data.splitlines())
def num_candidates(example: Example) -> int:
return sum(
op.apply(example.before, *example.data[1:]) == example.after
for op in OpCode
)
examples, data = parse(input)
return sum(num_candidates(example) >= 3 for example in examples)
def main() -> None:
input = sys.stdin.read()
print(solve(input))
if __name__ == "__main__":
main()