Advent of Code 2024 Day 13

Author

Nathan Moore

— Day 13: Claw Contraption —

We have a claw machine that can move in the x and y directions, at a cost.

Figure out how to win as many prizes as possible. What is the fewest tokens you would have to spend to win all possible prizes?

import re 
import numpy as np

with open('data-2024-13.txt', 'r') as f:
    inp = f.read().splitlines()

claw_list = []

for i in range(0, len(inp), 4): 
    butts = {}
    butts['ax'] = int(re.findall(r'X\+(\d+)', inp[i])[0])
    butts['ay'] = int(re.findall(r'Y\+(\d+)', inp[i])[0])
    butts['bx'] = int(re.findall(r'X\+(\d+)', inp[i+1])[0])
    butts['by'] = int(re.findall(r'Y\+(\d+)', inp[i+1])[0])
    butts['px'] = int(re.findall(r'X=(\d+)', inp[i+2])[0])
    butts['py'] = int(re.findall(r'Y=(\d+)', inp[i+2])[0])
    claw_list.append(butts)
    
# claw_list

Now, a function.

https://stackoverflow.com/questions/6789927/is-there-a-python-module-to-solve-linear-equations

>>> import numpy as np 
>>> a = np.array([[3,1], [1,2]]) 
>>> b = np.array([9,8]) 
>>> x = np.linalg.solve(a, b) 
>>> x 
array([ 2.,  3.]) 
summer = 0

def move_the_claw(dct): 
    d = np.array([[dct['ax'], dct['bx']], [dct['ay'], dct['by']]])
    e = np.array([dct['px'], dct['py']])
    f = np.linalg.solve(d, e)
    return f

for c in claw_list[:]: 
    solut = move_the_claw(c)
    # print(solut)
    if (solut[0] <= 100 and solut[0] > 0 and 
        solut[1] <= 100 and solut[1] > 0 and
        abs(round(solut[0]) - solut[0]) < 0.001 and 
        abs(round(solut[1]) - solut[1]) < 0.001): 
        # print('yes', solut)
        summer += 3*solut[0] + solut[1]


summer
    
# 27837
# 36578
# updated from int (which rounds down) to round for tolerance check 
np.float64(36758.0)

— Part Two —

Oops, the claw machines are way bigger than we thought, by lots

# 10,000,000,000,000

claw_list = []

for i in range(0, len(inp), 4): 
    butts = {}
    butts['ax'] = int(re.findall(r'X\+(\d+)', inp[i])[0])
    butts['ay'] = int(re.findall(r'Y\+(\d+)', inp[i])[0])
    butts['bx'] = int(re.findall(r'X\+(\d+)', inp[i+1])[0])
    butts['by'] = int(re.findall(r'Y\+(\d+)', inp[i+1])[0])
    butts['px'] = int(re.findall(r'X=(\d+)', inp[i+2])[0]) + 10000000000000
    butts['py'] = int(re.findall(r'Y=(\d+)', inp[i+2])[0]) + 10000000000000
    claw_list.append(butts)
    
claw_list[0]
{'ax': 64,
 'ay': 22,
 'bx': 19,
 'by': 58,
 'px': 10000000013478,
 'py': 10000000004424}

Use the same function, hopefully. I assume numpy has a pretty good solver!

summer = 0

for c in claw_list[:]: 
    solut = move_the_claw(c)
    # print(solut)
    if (solut[0] > 0 and 
        solut[1] > 0 and
        abs(round(solut[0]) - solut[0]) < 0.001 and 
        abs(round(solut[1]) - solut[1]) < 0.001): 
        # print('yes', solut)
        summer += 3*solut[0] + solut[1]


summer

# 76358113886726
np.float64(76358113886726.0)