Solved 2024/13 P1
This commit is contained in:
parent
f4bc6772f7
commit
2926202888
@ -14,33 +14,27 @@ input_f = 'input'
|
||||
# #
|
||||
#########################################
|
||||
|
||||
def get_neighbors(grid,node,visited):
|
||||
#print('@',node,' - Visited',visited)
|
||||
directions = {
|
||||
'up': (-1, 0),
|
||||
'down': (1, 0),
|
||||
'left': (0, -1),
|
||||
'right': (0, 1),
|
||||
}
|
||||
|
||||
directions = ['up','down','left','right']
|
||||
offsets = {
|
||||
'up': (-1, 0),
|
||||
'down': (1, 0),
|
||||
'left': (0, -1),
|
||||
'right': (0, 1),
|
||||
}
|
||||
def get_neighbors(grid,node,visited):
|
||||
neighbors = []
|
||||
for d in directions:
|
||||
for d in directions.keys():
|
||||
t = get_value_in_direction(grid,node)
|
||||
if get_value_in_direction(grid,node,d) == t:
|
||||
n = addTuples(offsets[d],node)
|
||||
n = addTuples(directions[d],node)
|
||||
if n not in visited:
|
||||
neighbors.append(n)
|
||||
#print(n)
|
||||
visited.append(n)
|
||||
neighbors+=get_neighbors(grid,n,visited)
|
||||
return neighbors
|
||||
|
||||
def part1():
|
||||
grid = toGrid(input_f)
|
||||
|
||||
#nprint(grid)
|
||||
values = {}
|
||||
visited = []
|
||||
total_plots = []
|
||||
for r,row in enumerate(grid):
|
||||
@ -54,20 +48,15 @@ def part1():
|
||||
plot += x
|
||||
if pos not in plot:
|
||||
plot.append(pos)
|
||||
if current not in values:
|
||||
values[current] = []
|
||||
|
||||
total_plots.append(plot)
|
||||
|
||||
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
|
||||
result = 0
|
||||
|
||||
for v in total_plots:
|
||||
|
||||
sides = 0
|
||||
for x,y in v:
|
||||
|
||||
for dx, dy in directions:
|
||||
for dx, dy in directions.values():
|
||||
neighbor = (x + dx, y + dy)
|
||||
if neighbor in v:
|
||||
sides += 1
|
||||
@ -88,29 +77,6 @@ print('Part 1:',part1(), '\t', round((time.time() - start_time)*1000), 'ms')
|
||||
# #
|
||||
#########################################
|
||||
|
||||
def get_neighbors_and_corners(grid,node,visited):
|
||||
|
||||
directions = ['up','down','left','right']
|
||||
offsets = {
|
||||
'up': (-1, 0),
|
||||
'down': (1, 0),
|
||||
'left': (0, -1),
|
||||
'right': (0, 1),
|
||||
}
|
||||
neighbors = []
|
||||
for d in directions:
|
||||
if get_value_in_direction(grid,node,d) == get_value_in_direction(grid,node):
|
||||
n = addTuples(offsets[d],node)
|
||||
if n not in visited:
|
||||
neighbors.append(n)
|
||||
visited.append(n)
|
||||
neighbors += get_neighbors_and_corners(grid,n,visited)
|
||||
|
||||
return neighbors
|
||||
|
||||
def rotate_90_clockwise(grid:list) -> list:
|
||||
return [list(row) for row in zip(*grid[::-1])]
|
||||
|
||||
def part2():
|
||||
grid = toGrid(input_f)
|
||||
#print(grid)
|
||||
@ -126,7 +92,7 @@ def part2():
|
||||
current = get_value_in_direction(grid,pos)
|
||||
if pos not in visited:
|
||||
|
||||
x = get_neighbors_and_corners(grid,pos,visited)
|
||||
x = get_neighbors(grid,pos,visited)
|
||||
plot += x
|
||||
if pos not in plot:
|
||||
plot.append(pos)
|
||||
|
126
2024/13/13.md
Normal file
126
2024/13/13.md
Normal file
@ -0,0 +1,126 @@
|
||||
## \-\-- Day 13: Claw Contraption \-\--
|
||||
|
||||
Next up: the [lobby](/2020/day/24) of a resort on a tropical island. The
|
||||
Historians take a moment to admire the hexagonal floor tiles before
|
||||
spreading out.
|
||||
|
||||
Fortunately, it looks like the resort has a new
|
||||
[arcade](https://en.wikipedia.org/wiki/Amusement_arcade)! Maybe you can
|
||||
win some prizes from the [claw
|
||||
machines](https://en.wikipedia.org/wiki/Claw_machine)?
|
||||
|
||||
The claw machines here are a little unusual. Instead of a joystick or
|
||||
directional buttons to control the claw, these machines have two buttons
|
||||
labeled `A` and `B`. Worse, you can\'t just put in a token and play; it
|
||||
costs *3 tokens* to push the `A` button and *1 token* to push the `B`
|
||||
button.
|
||||
|
||||
With a little experimentation, you figure out that each machine\'s
|
||||
buttons are configured to move the claw a specific amount to the *right*
|
||||
(along the `X` axis) and a specific amount *forward* (along the `Y`
|
||||
axis) each time that button is pressed.
|
||||
|
||||
Each machine contains one *prize*; to win the prize, the claw must be
|
||||
positioned *exactly* above the prize on both the `X` and `Y` axes.
|
||||
|
||||
You wonder: what is the smallest number of tokens you would have to
|
||||
spend to win as many prizes as possible? You assemble a list of every
|
||||
machine\'s button behavior and prize location (your puzzle input). For
|
||||
example:
|
||||
|
||||
Button A: X+94, Y+34
|
||||
Button B: X+22, Y+67
|
||||
Prize: X=8400, Y=5400
|
||||
|
||||
Button A: X+26, Y+66
|
||||
Button B: X+67, Y+21
|
||||
Prize: X=12748, Y=12176
|
||||
|
||||
Button A: X+17, Y+86
|
||||
Button B: X+84, Y+37
|
||||
Prize: X=7870, Y=6450
|
||||
|
||||
Button A: X+69, Y+23
|
||||
Button B: X+27, Y+71
|
||||
Prize: X=18641, Y=10279
|
||||
|
||||
This list describes the button configuration and prize location of four
|
||||
different claw machines.
|
||||
|
||||
For now, consider just the first claw machine in the list:
|
||||
|
||||
- Pushing the machine\'s `A` button would move the claw `94` units
|
||||
along the `X` axis and `34` units along the `Y` axis.
|
||||
- Pushing the `B` button would move the claw `22` units along the `X`
|
||||
axis and `67` units along the `Y` axis.
|
||||
- The prize is located at `X=8400`, `Y=5400`; this means that from the
|
||||
claw\'s initial position, it would need to move exactly `8400` units
|
||||
along the `X` axis and exactly `5400` units along the `Y` axis to be
|
||||
perfectly aligned with the prize in this machine.
|
||||
|
||||
The cheapest way to win the prize is by pushing the `A` button `80`
|
||||
times and the `B` button `40` times. This would line up the claw along
|
||||
the `X` axis (because `80*94 + 40*22 = 8400`) and along the `Y` axis
|
||||
(because `80*34 + 40*67 = 5400`). Doing this would cost `80*3` tokens
|
||||
for the `A` presses and
|
||||
`40*1` for the `B` presses, a total of `280` tokens.
|
||||
|
||||
For the second and fourth claw machines, there is no combination of A
|
||||
and B presses that will ever win a prize.
|
||||
|
||||
For the third claw machine, the cheapest way to win the prize is by
|
||||
pushing the `A` button `38` times and the `B` button `86` times. Doing
|
||||
this would cost a total of `200` tokens.
|
||||
|
||||
So, the most prizes you could possibly win is two; the minimum tokens
|
||||
you would have to spend to win all (two) prizes is `480`.
|
||||
|
||||
You estimate that each button would need to be pressed *no more than
|
||||
`100` times* to win a prize. How else would someone be expected to play?
|
||||
|
||||
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?*
|
||||
|
||||
Your puzzle answer was `30973`.
|
||||
|
||||
The first half of this puzzle is complete! It provides one gold star: \*
|
||||
|
||||
## \-\-- Part Two \-\-- {#part2}
|
||||
|
||||
As you go to win the first prize, you discover that the claw is nowhere
|
||||
near where you expected it would be. Due to a unit conversion error in
|
||||
your measurements, the position of every prize is actually
|
||||
`10000000000000` higher on both the `X` and `Y` axis!
|
||||
|
||||
Add `10000000000000` to the `X` and `Y` position of every prize. After
|
||||
making this change, the example above would now look like this:
|
||||
|
||||
Button A: X+94, Y+34
|
||||
Button B: X+22, Y+67
|
||||
Prize: X=10000000008400, Y=10000000005400
|
||||
|
||||
Button A: X+26, Y+66
|
||||
Button B: X+67, Y+21
|
||||
Prize: X=10000000012748, Y=10000000012176
|
||||
|
||||
Button A: X+17, Y+86
|
||||
Button B: X+84, Y+37
|
||||
Prize: X=10000000007870, Y=10000000006450
|
||||
|
||||
Button A: X+69, Y+23
|
||||
Button B: X+27, Y+71
|
||||
Prize: X=10000000018641, Y=10000000010279
|
||||
|
||||
Now, it is only possible to win a prize on the second and fourth claw
|
||||
machines. Unfortunately, it will take *many more than `100` presses* to
|
||||
do so.
|
||||
|
||||
Using the corrected prize coordinates, 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?*
|
||||
|
||||
Answer:
|
||||
|
||||
Although it hasn\'t changed, you can still [get your puzzle
|
||||
input](13/input).
|
||||
|
69
2024/13/solution.py
Normal file
69
2024/13/solution.py
Normal file
@ -0,0 +1,69 @@
|
||||
#!/bin/python3
|
||||
import sys,time,re
|
||||
from sympy import *
|
||||
from pprint import pprint
|
||||
sys.path.insert(0, '../../')
|
||||
from fred import list2int,get_re,nprint,lprint,loadFile
|
||||
start_time = time.time()
|
||||
|
||||
input_f = 'input'
|
||||
|
||||
#########################################
|
||||
# #
|
||||
# Part 1 #
|
||||
# #
|
||||
#########################################
|
||||
def part1():
|
||||
|
||||
instructions = []
|
||||
|
||||
with open(input_f) as file:
|
||||
for line in file:
|
||||
match = get_re(r".*X[\+|=](\d+), Y[\+|=](\d+)",line.rstrip())
|
||||
if match:
|
||||
instructions.append(list2int([match.group(1),match.group(2)]))
|
||||
|
||||
#print(instructions)
|
||||
a_cost = 3
|
||||
b_cost = 1
|
||||
|
||||
a = ()
|
||||
b = ()
|
||||
r = ()
|
||||
x,y = symbols('x y',integer=True)
|
||||
result = 0
|
||||
|
||||
for idx, inst in enumerate(instructions):
|
||||
#print(inst)
|
||||
|
||||
if idx%3 == 0:
|
||||
a = (inst[0],inst[1])
|
||||
elif idx%3 == 1:
|
||||
b = (inst[0],inst[1])
|
||||
elif idx%3 == 2:
|
||||
r = (inst[0],inst[1])
|
||||
eq1 = Eq(a[0]*x + b[0]*y,r[0])
|
||||
eq2 = Eq(a[1]*x + b[1]*y,r[1])
|
||||
|
||||
s = solve((eq1,eq2),(x,y))
|
||||
#print(s)
|
||||
if s:
|
||||
result += s[x]*a_cost
|
||||
result += s[y]*b_cost
|
||||
#input()
|
||||
return result
|
||||
|
||||
start_time = time.time()
|
||||
print('Part 1:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
||||
|
||||
|
||||
#########################################
|
||||
# #
|
||||
# Part 2 #
|
||||
# #
|
||||
#########################################
|
||||
def part1():
|
||||
return
|
||||
|
||||
start_time = time.time()
|
||||
print('Part 2:',part1(), '\t\t', round((time.time() - start_time)*1000), 'ms')
|
Binary file not shown.
6
fred.py
6
fred.py
@ -313,7 +313,7 @@ def grid_valid(x, y, grid):
|
||||
cols = len(grid[0])
|
||||
return 0 <= x < rows and 0 <= y < cols
|
||||
|
||||
def get_re(pattern, str):
|
||||
def get_re(pattern, line):
|
||||
"""
|
||||
Returns a match object if the pattern matches the string, else None.
|
||||
|
||||
@ -327,10 +327,10 @@ def get_re(pattern, str):
|
||||
Raises:
|
||||
TypeError: If str is not a string.
|
||||
"""
|
||||
if not isinstance(str, str):
|
||||
if not isinstance(line, str):
|
||||
raise TypeError("Input string must be of type str.")
|
||||
|
||||
match = re.match(pattern, str)
|
||||
match = re.match(pattern, line)
|
||||
if match:
|
||||
return match
|
||||
return None
|
||||
|
Loading…
Reference in New Issue
Block a user