Skip to content

Commit

Permalink
feat(2019): day 14 - wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rpidanny committed Jan 3, 2024
1 parent b1013a2 commit 41117a9
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 0 deletions.
3 changes: 3 additions & 0 deletions 2019/Day14/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.
3 changes: 3 additions & 0 deletions 2019/Day14/helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import math
import re
from collections import defaultdict
60 changes: 60 additions & 0 deletions 2019/Day14/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
11 BNMWF, 1 MRVFT, 10 PBNSF => 7 XSFVQ
149 ORE => 4 SMSB
1 XHQDX, 1 SVSTJ, 2 LDHX => 7 JMWQG
12 MJCLX => 9 PBNSF
132 ORE => 7 XPTXL
15 TZMWG, 1 LDHX, 1 PDVR => 7 LBQB
1 HJTD, 8 VFXHC => 2 SVSTJ
5 LBHQ, 6 MTQCB => 4 MHBZ
1 PRXT, 1 FWZN => 2 PBMPL
1 XPTXL => 1 HMRGM
10 XHPHR => 6 NSVJL
3 QZQLZ, 3 MTQCB => 4 TZMWG
5 LBHQ, 2 VPSDV => 3 ZFCD
13 WPFP => 6 ZXMGK
10 MHJMX, 75 LDHX, 52 JMWQG, 4 QWRB, 1 SVNVJ, 17 BNMWF, 18 GHVN => 1 FUEL
4 PFQRG, 14 XVNL => 5 PDCV
11 JMWQG, 10 ZBNCP => 6 NTJZH
14 PBMPL, 12 PRXT, 9 MJQS => 9 XVNL
9 GDNG, 13 LBQB => 9 QWRB
1 CXNM => 6 PFQRG
9 NTJZH, 7 BNMWF, 11 JCHP, 1 MHBZ, 1 SVSTJ, 9 XRDN => 5 SVNVJ
1 XHPHR, 1 GSMP => 4 THRVR
26 FWZN => 4 WPFP
35 VJTFJ, 2 XSFVQ, 6 HJVN, 1 NSVJL, 1 JCHP, 3 MJCLX, 1 QZNCK => 6 GHVN
1 WPFP, 3 XHPHR => 2 HJVN
5 SMSB => 7 HNCDS
111 ORE => 4 GSMP
6 LBHQ => 8 GDNG
2 GDNG, 5 MHBZ => 1 RNMKC
15 THRVR, 4 NWNSH, 1 NSVJL => 7 FDVH
2 HMRGM => 9 FWZN
6 MJQS, 5 JRZXM => 5 NWNSH
14 ZXMGK, 1 JTXWX => 6 DLWT
1 MJQS, 3 FWZN, 2 PRXT => 1 JTXWX
1 GSMP, 4 CXNM => 3 JRZXM
151 ORE => 9 ZNPRL
2 NTJZH, 1 DLWT, 3 ZBNCP => 9 MRVFT
14 SWZCB, 1 VPSDV => 7 XRDN
14 LBHQ, 16 FDVH, 9 PFQRG => 4 PRXT
22 CXNM => 9 HJTD
1 VFXHC, 1 MTQCB => 6 QZQLZ
6 SWZCB, 2 PDCV, 17 RNMKC => 9 LTHFW
4 ZNPRL => 6 CXNM
2 CXNM => 3 LBHQ
8 MHBZ, 2 QZQLZ, 2 LBQB => 3 VJTFJ
3 ZFCD => 1 XHQDX
1 VJTFJ, 7 MHBZ => 8 ZBNCP
5 CXNM => 2 VPSDV
7 MJQS => 9 VFXHC
2 LTHFW, 11 HJVN, 4 XRDN, 8 MRVFT, 3 NSVJL, 3 SVSTJ, 5 XSFVQ, 13 RNMKC => 8 MHJMX
2 HMRGM => 3 XHPHR
1 GDNG, 19 PDVR => 3 SWZCB
18 HMRGM, 10 HNCDS => 2 MJQS
6 HNCDS, 2 HMRGM, 1 LBHQ => 3 MTQCB
16 VJTFJ, 1 WPFP, 6 JMWQG => 6 BNMWF
3 TZMWG, 1 FWZN => 7 PDVR
10 ZXMGK => 4 QZNCK
32 LBQB, 1 ZBNCP => 1 JCHP
27 PDVR, 7 QZQLZ, 7 PBMPL => 3 MJCLX
5 MHBZ, 12 ZFCD => 4 LDHX
6 changes: 6 additions & 0 deletions 2019/Day14/input_test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
10 ORE => 10 A
1 ORE => 1 B
7 A, 1 B => 1 C
7 A, 1 C => 1 D
7 A, 1 D => 1 E
7 A, 1 E => 1 FUEL
7 changes: 7 additions & 0 deletions 2019/Day14/input_test_2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
9 ORE => 2 A
8 ORE => 3 B
7 ORE => 5 C
3 A, 4 B => 1 AB
5 B, 7 C => 1 BC
4 C, 1 A => 1 CA
2 AB, 3 BC, 4 CA => 1 FUEL
17 changes: 17 additions & 0 deletions 2019/Day14/input_test_3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
171 ORE => 8 CNZTR
7 ZLQW, 3 BMBT, 9 XCVML, 26 XMNCP, 1 WPTQ, 2 MZWV, 1 RJRHP => 4 PLWSL
114 ORE => 4 BHXH
14 VRPVC => 6 BMBT
6 BHXH, 18 KTJDG, 12 WPTQ, 7 PLWSL, 31 FHTLT, 37 ZDVW => 1 FUEL
6 WPTQ, 2 BMBT, 8 ZLQW, 18 KTJDG, 1 XMNCP, 6 MZWV, 1 RJRHP => 6 FHTLT
15 XDBXC, 2 LTCX, 1 VRPVC => 6 ZLQW
13 WPTQ, 10 LTCX, 3 RJRHP, 14 XMNCP, 2 MZWV, 1 ZLQW => 1 ZDVW
5 BMBT => 4 WPTQ
189 ORE => 9 KTJDG
1 MZWV, 17 XDBXC, 3 XCVML => 2 XMNCP
12 VRPVC, 27 CNZTR => 2 XDBXC
15 KTJDG, 12 BHXH => 5 XCVML
3 BHXH, 2 VRPVC => 7 MZWV
121 ORE => 7 VRPVC
7 XCVML => 6 RJRHP
5 BHXH, 4 VRPVC => 5 LTCX
16 changes: 16 additions & 0 deletions 2019/Day14/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))
67 changes: 67 additions & 0 deletions 2019/Day14/reactor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from collections import defaultdict

from sympy import *


class Chemical:
def __init__(self, quantity: str, name: str):
self.name = name
self.quantity = int(quantity)

def __repr__(self):
return f"{self.quantity} {self.name}"

def __str__(self):
return self.__repr__()


class ChemicalReactions:
def __init__(self, ip: list[Chemical], op: Chemical):
self.ip = ip
self.op = op

def __repr__(self):
return f"Input: {self.ip} --> Output: {self.op}"

def __str__(self):
return self.__repr__()


class Reactor:
def __init__(self, inputs: list[str]):
self.reactions = self.parse_input(inputs)
self.chemicals = defaultdict(int)
self.output_map = {x.op.name: x for x in self.reactions}

def parse_input(self, inputs: list[str]):
reactions = []
for line in inputs:
ip, op = line.split(" => ")
ip = ip.split(", ")
ip = [Chemical(*x.split(" ")) for x in ip]
op = Chemical(*op.split(" "))
reactions.append(ChemicalReactions(ip, op))
return reactions

def get_ore(self, chemical: str, quantity: int):
if chemical == "ORE":
self.chemicals["ORE"] += quantity
return quantity
if self.chemicals[chemical] >= quantity:
self.chemicals[chemical] -= quantity
return 0
else:
quantity -= self.chemicals[chemical]
self.chemicals[chemical] = 0
reaction = self.output_map[chemical]
multiplier = quantity // reaction.op.quantity
if quantity % reaction.op.quantity != 0:
multiplier += 1
ore = 0
for ip in reaction.ip:
ore += self.get_ore(ip.name, ip.quantity * multiplier)
self.chemicals[chemical] += reaction.op.quantity * multiplier - quantity
return ore

def get_ore_for_fuel(self, quantity: int):
return 1
15 changes: 15 additions & 0 deletions 2019/Day14/solutions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from reactor import Reactor


def part1(inputs: list[str]) -> int:
reactor = Reactor(inputs)
print(reactor.output_map)
ore = reactor.get_ore("FUEL", 1)

print(reactor.chemicals)
return ore


def part2(inputs: list[str], ore=1000000000000) -> int:
reactor = Reactor(inputs)
return reactor.get_ore_for_fuel(ore)
42 changes: 42 additions & 0 deletions 2019/Day14/test_solutions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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")
input_test = get_inputs(f"{current_dir}/input_test.txt")
input_test_2 = get_inputs(f"{current_dir}/input_test_2.txt")
input_test_3 = get_inputs(f"{current_dir}/input_test_3.txt")


# @pytest.mark.skip(reason="not implemented")
class TestPart1:
@pytest.mark.skip(reason="not implemented")
def test_with_test_data(self):
assert part1(input_test) == 31

# @pytest.mark.skip(reason="not implemented")
def test_with_test_data_2(self):
assert part1(input_test_2) == 165

@pytest.mark.skip(reason="not implemented")
def test_with_test_data_3(self):
assert part1(input_test_3) == 2210736

@pytest.mark.skip(reason="not implemented")
def test_with_real_data(self):
assert part1(input) == 485720


class TestPart2:
# @pytest.mark.skip(reason="not implemented")
def test_with_test_data_3(self):
assert part2(input_test_3) == 460664

@pytest.mark.skip(reason="not implemented")
def test_with_real_data(self):
assert part2(input) == 2

0 comments on commit 41117a9

Please sign in to comment.