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

  • @TunaCowboy
    link
    2
    edit-2
    12 days ago

    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()
    
      • @TunaCowboy
        link
        1
        edit-2
        12 days ago

        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.

        • @[email protected]
          link
          fedilink
          English
          1
          edit-2
          12 days ago

          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)