1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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))
|