this post was submitted on 07 Dec 2024
22 points (89.3% liked)

Advent Of Code

987 readers
8 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2024

Solution Threads

M T W T F S S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 1 year ago
MODERATORS
 

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

you are viewing a single comment's thread
view the rest of the comments
[โ€“] janAkali@lemmy.one 2 points 3 weeks ago* (last edited 3 weeks ago)

Nim

Bruteforce, my beloved.

Wasted too much time on part 2 trying to make combinations iterator (it was very slow). In the end solved both parts with 3^n and toTernary.

Runtime: 1.5s

func digits(n: int): int =
  result = 1; var n = n
  while (n = n div 10; n) > 0: inc result

func concat(a: var int, b: int) =
  a = a * (10 ^ b.digits) + b

func toTernary(n: int, len: int): seq[int] =
  result = newSeq[int](len)
  if n == 0: return
  var n = n
  for i in 0..<len:
    result[i] = n mod 3
    n = n div 3

proc solve(input: string): AOCSolution[int, int] =
  for line in input.splitLines():
    let parts = line.split({':',' '})
    let res = parts[0].parseInt
    var values: seq[int]
    for i in 2..parts.high:
      values.add parts[i].parseInt

    let opsCount = values.len - 1
    var solvable = (p1: false, p2: false)
    for s in 0 ..< 3^opsCount:
      var sum = values[0]
      let ternary = s.toTernary(opsCount)
      for i, c in ternary:
        case c
        of 0: sum *= values[i+1]
        of 1: sum += values[i+1]
        of 2: sum.concat values[i+1]
        else: raiseAssert"!!"
      if sum == res:
        if ternary.count(2) == 0:
          solvable.p1 = true
        solvable.p2 = true
        if solvable == (true, true): break
    if solvable.p1: result.part1 += res
    if solvable.p2: result.part2 += res

Codeberg repo