summaryrefslogtreecommitdiffstats
path: root/19/py/d14.py
diff options
context:
space:
mode:
Diffstat (limited to '19/py/d14.py')
-rw-r--r--19/py/d14.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/19/py/d14.py b/19/py/d14.py
new file mode 100644
index 0000000..1d628a4
--- /dev/null
+++ b/19/py/d14.py
@@ -0,0 +1,77 @@
+import math
+
+class Chem(object):
+ def __init__(self, name, created):
+ self.name = name
+ self.created = created
+
+ self.amount = 0
+ self.left_over = 0
+ self.producers = {}
+
+ def add_producer(self, producer, amount):
+ self.producers[producer] = amount
+
+ def produce(self, to_create):
+ if self.name == "ORE":
+ self.amount += to_create
+ return
+ if self.left_over > 0:
+ if self.left_over < to_create:
+ to_create -= self.left_over
+ self.left_over = 0
+ else:
+ self.left_over -= to_create
+ to_create = 0
+ productions = math.ceil(to_create / self.created)
+ self.amount += productions * self.created
+ self.left_over += productions * self.created - to_create
+ for producer, amount in self.producers.items():
+ producer.produce(productions * amount)
+
+ def __repr__(self):
+ return str((self.name, self.amount))
+
+def read_chems(input):
+ chems = {"ORE": Chem("ORE", 1)}
+ for line in input:
+ output = line.strip().split(" => ")[1]
+ chems[output.split(" ")[1]] = Chem(output.split(" ")[1], int(output.split(" ")[0]))
+
+ for line in input:
+ inputs = line.strip().split(" => ")[0]
+ output = line.strip().split(" => ")[1]
+ for i in inputs.split(", "):
+ chems[output.split(" ")[1]] \
+ .add_producer(chems[i.split(" ")[1]], int(i.split(" ")[0]))
+ return chems
+
+def pt1(input, amount=1):
+ chems = read_chems(input)
+ chems["FUEL"].produce(amount)
+ return chems["ORE"].amount
+
+def pt2(input):
+ low, high = 0, int(1e9)
+ target = 1000000000000
+ prev_guess = 0
+ while low != high:
+ guess = (low+high) // 2
+ if guess == prev_guess:
+ break
+ prev_guess = guess
+ chems = read_chems(input)
+ chems["FUEL"].produce(guess)
+ if chems["ORE"].amount == target:
+ break
+ elif chems["ORE"].amount > target:
+ high = guess
+ else:
+ low = guess
+ #print(low, guess, high)
+ return guess
+
+if __name__ == "__main__":
+ input = open("../input/14", "r").readlines()
+ print(pt1(input))
+ print(pt2(input))