Day 7: Bridge Repair
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
python
45s on my machine for first shot, trying to break my will to brute force π . Iβll try improving on it in a bit after I smoke another bowl and grab another drink.
solution
import itertools
import re
import aoc
def ltr(e):
r = int(e[0])
for i in range(1, len(e), 2):
o = e[i]
n = int(e[i + 1])
if o == '+':
r += n
elif o == '*':
r *= n
elif o == '||':
r = int(f"{r}{n}")
return r
def pl(l, os):
d = [int(x) for x in re.findall(r'\d+', l)]
t, ns = d[0], d[1:]
ops = list(itertools.product(os, repeat=len(ns) - 1))
for o in ops:
e = str(ns[0])
for i, op in enumerate(o):
e += f" {op} {ns[i + 1]}"
r = ltr(e.split())
if r == t:
return r
return 0
def one():
lines = aoc.get_lines(7)
acc = 0
for l in lines:
acc += pl(l, ['+', '*'])
print(acc)
def two():
lines = aoc.get_lines(7)
acc = 0
for l in lines:
acc += pl(l, ['+', '*', '||'])
print(acc)
one()
two()
a
e
o
, Killer Tofu. Thatβs all I can think of reading this code.
Itβs not a long lived project, itβs a puzzle, and once solved never needs to run again. My objective here is to get the correct answer, not win a style contest.
Can you provide a link to your solution? Iβd like to check it out.
My initial comment was a bit harsh, Iβm sorry for that. It was meant to be a bit of a joke. Anyway hereβs my code. Do note that I donβt do the challenges timed so I have a bit more time to name my variables accordingly. Takes 35 seconds to run on a pc with a AMD Ryzen 5 5600
import sys
from tqdm import tqdm
input = sys.stdin.read()
def all_operator_permutations(operator_count):
if operator_count == 0:
return [[]]
smaller_permutations = all_operator_permutations(operator_count-1)
return [
*[['+', *ops] for ops in smaller_permutations],
*[['*', *ops] for ops in smaller_permutations],
*[['||', *ops] for ops in smaller_permutations],
]
def test_operators(ops, values):
res = values.pop(0)
for op in ops:
match op:
case '*':
res *= values.pop(0)
case '+':
res += values.pop(0)
case '||':
res = int(f"{res}{values.pop(0)}")
return res
total_calibration_result = 0
for line in tqdm(input.splitlines()[:]):
target, *tail = line.split(':')
target = int(target)
values = [int(val) for val in tail[0].split()]
all_perms = all_operator_permutations(len(values) - 1)
ops = all_perms.pop()
while True:
res = test_operators(ops, values.copy())
if res == target:
total_calibration_result += target
break
if not all_perms:
break
ops = all_perms.pop()
print(total_calibration_result)