1+ #!/usr/bin/env python
2+ # -*- coding: utf-8 -*-
3+
4+ from re import findall
5+
6+ def parse (data ):
7+ machines = []
8+
9+ for machine in data .split ("\n \n " ):
10+ Ax ,Ay ,Bx ,By ,Px ,Py = findall (r"(\d+)" , machine )
11+ machines .append ((int (Ax ),int (Ay ),int (Bx ),int (By ),int (Px ),int (Py )))
12+
13+ return machines
14+
15+ split_data = parse
16+ completed = True
17+ raw_data = None # Not To be touched
18+
19+ def part1 (data ):
20+ # This can be solved quickly using some simple math
21+ tokens = 0
22+ for machine in data :
23+ Ax ,Ay ,Bx ,By ,Px ,Py = machine
24+
25+ for Bpress in range (101 ):
26+ pending = Px - Bpress * Bx
27+ if pending < 0 : break # Looks like we are over shooting here...
28+ Apress = pending / Ax
29+ if Apress % 1 != 0 or Apress > 100 :
30+ continue # Not a valid solution
31+
32+ # By now Bpress is atmost 100, Apress is atmost 100 and both are integers
33+ if Bpress * By + Apress * Ay == Py :
34+ assert Apress * Ax + Bpress * Bx == Px # Just a flex!
35+ tokens += Apress * 3 + Bpress
36+ break
37+
38+ return int (tokens )
39+
40+ def part2 (data ):
41+ # We can do some simple math on paper and come up with the formula
42+ # Ax * x + Bx * y = Px
43+ # Ay * x + By * y = Py
44+
45+ # https://www.desmos.com/calculator/h566btcmir
46+
47+ tokens = 0
48+ for machine in data :
49+ Ax ,Ay ,Bx ,By ,Px ,Py = machine
50+ Px += 10000000000000 # The only change
51+ Py += 10000000000000 # The only change
52+
53+ aPress = ((By * Px ) - (Bx * Py ))/ ((By * Ax ) - (Bx * Ay ))
54+ if aPress % 1 != 0 or aPress < 0 : continue # We only accept integer solutions
55+ bPress = (Px - aPress * Ax )/ Bx
56+ if bPress % 1 != 0 or aPress < 0 : continue # We only accept integer solutions
57+
58+ # print(aPress, bPress)
59+ assert aPress * Ax + bPress * Bx == Px and aPress * Ay + bPress * By == Py # Just a flex!
60+ tokens += aPress * 3 + bPress
61+
62+
63+ return int (tokens )
0 commit comments