Solved 2024/07 P1+P2
This commit is contained in:
parent
21f5c91742
commit
a8dbb6bd22
103
2024/07/7.md
Normal file
103
2024/07/7.md
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
## \-\-- Day 7: Bridge Repair \-\--
|
||||||
|
|
||||||
|
The Historians take you to a familiar [rope bridge](/2022/day/9) over a
|
||||||
|
river in the middle of a jungle. The Chief isn\'t on this side of the
|
||||||
|
bridge, though; maybe he\'s on the other side?
|
||||||
|
|
||||||
|
When you go to cross the bridge, you notice a group of engineers trying
|
||||||
|
to repair it. (Apparently, it breaks pretty frequently.) You won\'t be
|
||||||
|
able to cross until it\'s fixed.
|
||||||
|
|
||||||
|
You ask how long it\'ll take; the engineers tell you that it only needs
|
||||||
|
final calibrations, but some young elephants were playing nearby and
|
||||||
|
*stole all the operators* from their calibration equations! They could
|
||||||
|
finish the calibrations if only someone could determine which test
|
||||||
|
values could possibly be produced by placing any combination of
|
||||||
|
operators into their calibration equations (your puzzle input).
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
190: 10 19
|
||||||
|
3267: 81 40 27
|
||||||
|
83: 17 5
|
||||||
|
156: 15 6
|
||||||
|
7290: 6 8 6 15
|
||||||
|
161011: 16 10 13
|
||||||
|
192: 17 8 14
|
||||||
|
21037: 9 7 18 13
|
||||||
|
292: 11 6 16 20
|
||||||
|
|
||||||
|
Each line represents a single equation. The test value appears before
|
||||||
|
the colon on each line; it is your job to determine whether the
|
||||||
|
remaining numbers can be combined with operators to produce the test
|
||||||
|
value.
|
||||||
|
|
||||||
|
Operators are *always evaluated left-to-right*, *not* according to
|
||||||
|
precedence rules. Furthermore, numbers in the equations cannot be
|
||||||
|
rearranged. Glancing into the jungle, you can see elephants holding two
|
||||||
|
different types of operators: *add* (`+`) and *multiply* (`*`).
|
||||||
|
|
||||||
|
Only three of the above equations can be made true by inserting
|
||||||
|
operators:
|
||||||
|
|
||||||
|
- `190: 10 19` has only one position that accepts an operator: between
|
||||||
|
`10` and `19`. Choosing `+` would give `29`, but choosing `*` would
|
||||||
|
give the test value (`10 * 19 = 190`).
|
||||||
|
- `3267: 81 40 27` has two positions for operators. Of the four
|
||||||
|
possible configurations of the operators, *two* cause the right side
|
||||||
|
to match the test value: `81 + 40 * 27` and `81 * 40 + 27` both
|
||||||
|
equal `3267` (when evaluated left-to-right)!
|
||||||
|
- `292: 11 6 16 20` can be solved in exactly one way:
|
||||||
|
`11 + 6 * 16 + 20`.
|
||||||
|
|
||||||
|
The engineers just need the *total calibration result*, which is the sum
|
||||||
|
of the test values from just the equations that could possibly be true.
|
||||||
|
In the above example, the sum of the test values for the three equations
|
||||||
|
listed above is `3749`.
|
||||||
|
|
||||||
|
Determine which equations could possibly be true. *What is their total
|
||||||
|
calibration result?*
|
||||||
|
|
||||||
|
Your puzzle answer was `1038838357795`.
|
||||||
|
|
||||||
|
## \-\-- Part Two \-\-- {#part2}
|
||||||
|
|
||||||
|
The engineers seem concerned; the total calibration result you gave them
|
||||||
|
is nowhere close to being within safety tolerances. Just then, you spot
|
||||||
|
your mistake: some well-hidden elephants are holding a *third type of
|
||||||
|
operator*.
|
||||||
|
|
||||||
|
The
|
||||||
|
[concatenation](https://en.wikipedia.org/wiki/Concatenation)
|
||||||
|
operator (`||`) combines the digits from its left and right inputs into
|
||||||
|
a single number. For example, `12 || 345` would become `12345`. All
|
||||||
|
operators are still evaluated left-to-right.
|
||||||
|
|
||||||
|
Now, apart from the three equations that could be made true using only
|
||||||
|
addition and multiplication, the above example has three more equations
|
||||||
|
that can be made true by inserting operators:
|
||||||
|
|
||||||
|
- `156: 15 6` can be made true through a single concatenation:
|
||||||
|
`15 || 6 = 156`.
|
||||||
|
- `7290: 6 8 6 15` can be made true using `6 * 8 || 6 * 15`.
|
||||||
|
- `192: 17 8 14` can be made true using `17 || 8 + 14`.
|
||||||
|
|
||||||
|
Adding up all six test values (the three that could be made before using
|
||||||
|
only `+` and `*` plus the new three that can now be made by also using
|
||||||
|
`||`) produces the new *total calibration result* of `11387`.
|
||||||
|
|
||||||
|
Using your new knowledge of elephant hiding spots, determine which
|
||||||
|
equations could possibly be true. *What is their total calibration
|
||||||
|
result?*
|
||||||
|
|
||||||
|
Your puzzle answer was `254136560217241`.
|
||||||
|
|
||||||
|
Both parts of this puzzle are complete! They provide two gold stars:
|
||||||
|
\*\*
|
||||||
|
|
||||||
|
At this point, you should [return to your Advent calendar](/2024) and
|
||||||
|
try another puzzle.
|
||||||
|
|
||||||
|
If you still want to see it, you can [get your puzzle
|
||||||
|
input](7/input).
|
||||||
|
|
77
2024/07/solution.py
Normal file
77
2024/07/solution.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import sys,re
|
||||||
|
from pprint import pprint
|
||||||
|
sys.path.insert(0, '../../')
|
||||||
|
from fred import list2int,get_re,nprint,lprint
|
||||||
|
|
||||||
|
input_f = 'input'
|
||||||
|
|
||||||
|
part = 2
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 1 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
|
||||||
|
def loadFile(input_f):
|
||||||
|
# For some reason, when this is a dict {}
|
||||||
|
# and i use instructions[int(a[0])] = list2int(b)
|
||||||
|
# the line with 360: 8 3 7 4 1 is not used in the
|
||||||
|
# for loop that runs through all the instructions.
|
||||||
|
|
||||||
|
instructions = []
|
||||||
|
|
||||||
|
with open(input_f) as file:
|
||||||
|
for line in file:
|
||||||
|
a = line.rstrip().split(': ')
|
||||||
|
b = a[1].split(' ')
|
||||||
|
|
||||||
|
instructions.append([int(a[0]),list2int(b)])
|
||||||
|
return instructions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if part == 1:
|
||||||
|
def calculateResult(a:int,b:list,result:int):
|
||||||
|
|
||||||
|
if not b:
|
||||||
|
return result if result == a else 0
|
||||||
|
|
||||||
|
add = calculateResult(a,b[1:],b[0]+result)
|
||||||
|
mul = calculateResult(a,b[1:],b[0]*result)
|
||||||
|
return add or mul
|
||||||
|
instructions = loadFile(input_f)
|
||||||
|
result = 0
|
||||||
|
|
||||||
|
for idx,i in enumerate(instructions):
|
||||||
|
result += calculateResult(instructions[idx][0],instructions[idx][1],0)
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
|
||||||
|
#########################################
|
||||||
|
# #
|
||||||
|
# Part 2 #
|
||||||
|
# #
|
||||||
|
#########################################
|
||||||
|
if part == 2:
|
||||||
|
|
||||||
|
def calculateResult2(a:int,b:list,result:int):
|
||||||
|
|
||||||
|
if not b:
|
||||||
|
return result if result == a else 0
|
||||||
|
|
||||||
|
add = calculateResult2(a,b[1:],b[0]+result)
|
||||||
|
mul = calculateResult2(a,b[1:],b[0]*result)
|
||||||
|
# Issues happened when i did b[0]||result. Reversing it
|
||||||
|
# gave me the right result.
|
||||||
|
con = calculateResult2(a,b[1:],int(str(result)+str(b[0])))
|
||||||
|
return add or mul or con
|
||||||
|
|
||||||
|
instructions = loadFile(input_f)
|
||||||
|
result = 0
|
||||||
|
|
||||||
|
for idx,i in enumerate(instructions):
|
||||||
|
print('Line',(idx+1),i)
|
||||||
|
result += calculateResult2(instructions[idx][0],instructions[idx][1],0)
|
||||||
|
print(result)
|
||||||
|
|
23
2024/07/test.py
Normal file
23
2024/07/test.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import sys
|
||||||
|
|
||||||
|
file = open(sys.argv[1]).read()
|
||||||
|
|
||||||
|
lines = [line.split(": ") for line in file.splitlines()]
|
||||||
|
lines = [(int(test), list(map(int, args.split()))) for test, args in lines]
|
||||||
|
|
||||||
|
star, plus, concat = lambda x, y: x * y, lambda x, y: x + y, lambda x, y: int(f"{x}{y}")
|
||||||
|
def solve(targ, args, operators):
|
||||||
|
def inner(targ, args, curr):
|
||||||
|
if curr > targ:
|
||||||
|
return False
|
||||||
|
match args:
|
||||||
|
case []:
|
||||||
|
return curr == targ
|
||||||
|
case [arg, *rest]:
|
||||||
|
return any(inner(targ, rest, op(curr, arg)) for op in operators)
|
||||||
|
|
||||||
|
return inner(targ, args[1:], args[0])
|
||||||
|
|
||||||
|
|
||||||
|
print(sum(targ for targ, args in lines if solve(targ, args, [star, plus])))
|
||||||
|
print(sum(targ for targ, args in lines if solve(targ, args, [star, plus, concat])))
|
Loading…
Reference in New Issue
Block a user