mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implement 2019 day 2
Start of the intcode madness
This commit is contained in:
33
2019/aoc2019/day02.py
Normal file
33
2019/aoc2019/day02.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
from typing import TextIO
|
||||||
|
|
||||||
|
from aoc2019.intcode import read_program, Computer
|
||||||
|
|
||||||
|
|
||||||
|
def part1(data: TextIO) -> int:
|
||||||
|
program = read_program(data)
|
||||||
|
|
||||||
|
program[1] = 12
|
||||||
|
program[2] = 2
|
||||||
|
|
||||||
|
computer = Computer(program)
|
||||||
|
computer.run()
|
||||||
|
|
||||||
|
return computer[0]
|
||||||
|
|
||||||
|
|
||||||
|
def part2(data: TextIO) -> int:
|
||||||
|
program = read_program(data)
|
||||||
|
|
||||||
|
for verb in range(100):
|
||||||
|
for noun in range(100):
|
||||||
|
computer = Computer(program.copy())
|
||||||
|
|
||||||
|
computer[1] = noun
|
||||||
|
computer[2] = verb
|
||||||
|
|
||||||
|
computer.run()
|
||||||
|
|
||||||
|
if computer[0] == 19690720:
|
||||||
|
return 100 * noun + verb
|
||||||
|
|
||||||
|
raise ValueError('Did not find valid combination')
|
||||||
59
2019/aoc2019/intcode.py
Normal file
59
2019/aoc2019/intcode.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
from typing import List, TextIO
|
||||||
|
|
||||||
|
|
||||||
|
def read_program(data: TextIO) -> List[int]:
|
||||||
|
line = next(data)
|
||||||
|
|
||||||
|
return [int(i) for i in line.split(',')]
|
||||||
|
|
||||||
|
|
||||||
|
class Computer:
|
||||||
|
program: List[int]
|
||||||
|
pointer: int
|
||||||
|
|
||||||
|
def __init__(self, program: List[int], pointer: int = 0) -> None:
|
||||||
|
self.program = program
|
||||||
|
self.pointer = pointer
|
||||||
|
|
||||||
|
def __getitem__(self, item: int) -> int:
|
||||||
|
self._ensure_length(item + 1)
|
||||||
|
return self.program[item]
|
||||||
|
|
||||||
|
def __setitem__(self, key: int, value: int) -> None:
|
||||||
|
self._ensure_length(key + 1)
|
||||||
|
self.program[key] = value
|
||||||
|
|
||||||
|
def _ensure_length(self, length: int) -> None:
|
||||||
|
if len(self.program) < length:
|
||||||
|
# Double current program size with 0s
|
||||||
|
self.program.extend(0 for _ in range(len(self.program)))
|
||||||
|
|
||||||
|
def run(self) -> None:
|
||||||
|
""" Run until failure"""
|
||||||
|
while self._execute_current():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _execute_current(self) -> bool:
|
||||||
|
"""
|
||||||
|
Execute a single instruction
|
||||||
|
:return: True if the program should continue
|
||||||
|
"""
|
||||||
|
pointer = self.pointer
|
||||||
|
opcode = self[pointer]
|
||||||
|
|
||||||
|
if opcode == 1:
|
||||||
|
# Add
|
||||||
|
self[self[pointer + 3]] = self[self[pointer + 1]] + self[self[pointer + 2]]
|
||||||
|
self.pointer += 4
|
||||||
|
elif opcode == 2:
|
||||||
|
# Multiply
|
||||||
|
self[self[pointer + 3]] = self[self[pointer + 1]] * self[self[pointer + 2]]
|
||||||
|
self.pointer += 4
|
||||||
|
elif opcode == 99:
|
||||||
|
# Halt
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unknown opcode {opcode} at {pointer}')
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
20
2019/tests/test_intcode.py
Normal file
20
2019/tests/test_intcode.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from aoc2019.intcode import Computer
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('program,expected', [
|
||||||
|
([1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50], [3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50]),
|
||||||
|
([1, 0, 0, 0, 99], [2, 0, 0, 0, 99]),
|
||||||
|
([2, 3, 0, 3, 99], [2, 3, 0, 6, 99]),
|
||||||
|
([2, 4, 4, 5, 99, 0], [2, 4, 4, 5, 99, 9801]),
|
||||||
|
([1, 1, 1, 4, 99, 5, 6, 0, 99], [30, 1, 1, 4, 2, 5, 6, 0, 99])
|
||||||
|
])
|
||||||
|
def test_instructions_day2(program: List[int], expected: List[int]) -> None:
|
||||||
|
computer = Computer(program)
|
||||||
|
|
||||||
|
computer.run()
|
||||||
|
|
||||||
|
assert computer.program == expected
|
||||||
Reference in New Issue
Block a user