Day 11: Plutonian Pebbles
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
Nim
Runtime: 30-40 ms
I’m not very experienced with recursion and memoization, so this took me quite a while.
Edit: slightly better version
template splitNum(numStr: string): seq[int] = @[parseInt(numStr[0..<numStr.len div 2]), parseInt(numStr[numStr.len div 2..^1])] template applyRule(stone: int): seq[int] = if stone == 0: @[1] else: let numStr = $stone if numStr.len mod 2 == 0: splitNum(numStr) else: @[stone * 2024] proc memRule(st: int): seq[int] = var memo {.global.}: Table[int, seq[int]] if st in memo: return memo[st] result = st.applyRule memo[st] = result proc countAfter(stone: int, targetBlinks: int): int = var memo {.global.}: Table[(int, int), int] if (stone,targetBlinks) in memo: return memo[(stone,targetBlinks)] if targetBlinks == 0: return 1 for st in memRule(stone): result += st.countAfter(targetBlinks - 1) memo[(stone,targetBlinks)] = result proc solve(input: string): AOCSolution[int, int] = for stone in input.split.map(parseInt): result.part1 += stone.countAfter(25) result.part2 += stone.countAfter(75)
Codeberg repo