Skip to content

Commit

Permalink
feat(2019): day 7 - part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
rpidanny committed Dec 11, 2023
1 parent 26e6051 commit 4e622ff
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 0 deletions.
3 changes: 3 additions & 0 deletions 2019/Day07/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# --- Day 0: Template ---

To be used as template for the other days.
19 changes: 19 additions & 0 deletions 2019/Day07/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from copy import deepcopy
import sys

sys.path.append("utils")

from intcode import get_program, run_program


def amplify(inputs: list[str], phases: list[int], input: int) -> int:
program = get_program(inputs)

output = input
for amp in range(len(phases)):
mem = deepcopy(program)
io_ip = [phases[amp], output]
io_op = []
run_program(mem, io_ip, io_op)
output = io_op[0]
return output
1 change: 1 addition & 0 deletions 2019/Day07/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3,8,1001,8,10,8,105,1,0,0,21,42,51,76,101,118,199,280,361,442,99999,3,9,101,5,9,9,102,2,9,9,1001,9,4,9,102,2,9,9,4,9,99,3,9,1002,9,3,9,4,9,99,3,9,1002,9,4,9,1001,9,3,9,1002,9,5,9,101,3,9,9,1002,9,2,9,4,9,99,3,9,101,4,9,9,1002,9,2,9,1001,9,3,9,1002,9,3,9,101,4,9,9,4,9,99,3,9,101,3,9,9,1002,9,3,9,101,2,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,99
Empty file added 2019/Day07/input_test.txt
Empty file.
16 changes: 16 additions & 0 deletions 2019/Day07/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import os
import sys

sys.path.append(".")

from solutions import part1, part2

from utils.inputs import get_inputs
from utils.timings import profile_run

if __name__ == "__main__":
input_path = f"{os.path.dirname(os.path.realpath(__file__))}/input.txt"
inputs = get_inputs(input_path)

profile_run("Part 1", lambda: part1(inputs))
profile_run("Part 2", lambda: part2(inputs))
17 changes: 17 additions & 0 deletions 2019/Day07/solutions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from itertools import permutations

from helpers import amplify


def part1(inputs: list[str]) -> int:
max_output = 0
for phases in list(permutations(range(5), 5)):
max_output = max(max_output, amplify(inputs, list(phases), 0))
return max_output


def part2(inputs: list[str]) -> int:
max_output = 0
for phases in list(permutations(range(9), 5)):
max_output = max(max_output, amplify(inputs, list(phases), 0))
return max_output
51 changes: 51 additions & 0 deletions 2019/Day07/test_solutions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import os

import pytest
from solutions import part1, part2

from utils.inputs import get_inputs

current_dir = os.path.dirname(os.path.realpath(__file__))

input = get_inputs(f"{current_dir}/input.txt")


@pytest.mark.skip(reason="completed")
class TestPart1:
def test_with_test_data_1(self):
assert part1(["3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0"]) == 43210
assert (
part1(
[
"3,23,3,24,1002,24,10,24,1002,23,-1,23,101,5,23,23,1,24,23,23,4,23,99,0,0"
]
)
== 54321
)
assert (
part1(
[
"3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0"
]
)
== 65210
)

def test_with_real_data(self):
assert part1(input) == 75228


class TestPart2:
def test_with_test_data(self):
assert (
part2(
[
"3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5"
]
)
== 139629729
)

@pytest.mark.skip(reason="not implemented")
def test_with_real_data(self):
assert part2(input) == 2
44 changes: 44 additions & 0 deletions 2019/utils/intcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,47 @@ def parse_instruction(instr: int) -> Tuple[int, int, int, int]:
op_code = int(instr[-2:])
m_3, m_2, m_1 = map(int, instr[:3])
return m_3, m_2, m_1, op_code


def run_program(
mem: list[int], io_ip: list[int] = [], io_op: list[int] = []
) -> list[int]:
ip = 0

def get_val(addr: int, mode: int) -> int:
return mem[addr] if mode else mem[mem[addr]]

num_params = {1: 3, 2: 3, 3: 1, 4: 1, 5: 2, 6: 2, 7: 3, 8: 3, 99: 0}

while True:
_, m_2, m_1, op_code = parse_instruction(mem[ip])

jump = False

if op_code == 1:
mem[mem[ip + 3]] = get_val(ip + 1, m_1) + get_val(ip + 2, m_2)
elif op_code == 2:
mem[mem[ip + 3]] = get_val(ip + 1, m_1) * get_val(ip + 2, m_2)
elif op_code == 3:
mem[mem[ip + 1]] = io_ip.pop(0)
elif op_code == 4:
io_op.append(get_val(ip + 1, m_1))
elif op_code == 5:
if jump := get_val(ip + 1, m_1) > 0:
ip = get_val(ip + 2, m_2)
elif op_code == 6:
if jump := get_val(ip + 1, m_1) == 0:
ip = get_val(ip + 2, m_2)
elif op_code == 7:
mem[mem[ip + 3]] = 1 if get_val(ip + 1, m_1) < get_val(ip + 2, m_2) else 0
elif op_code == 8:
mem[mem[ip + 3]] = 1 if get_val(ip + 1, m_1) == get_val(ip + 2, m_2) else 0
elif op_code == 99:
break
else:
raise Exception(f"Unknown opcode: {op_code}")

if not jump:
ip += num_params[op_code] + 1

return mem

0 comments on commit 4e622ff

Please sign in to comment.