Day 2: Gift Shop ## 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
C
There are interesting analytical observations to be made about the problem to sidestep most of the actual iteration, but I wasn’t up to working it all out and the runtime was pretty much instant anyway.
Here’s my original solution with ints, using divions with powers of 10 to do the splitting: day02-u64.c
But I’m only doing the C implementations to prototype my assembly solutions, and dealing with 64-bit numbers, especially divisions, on x86-16 is painful, so I rewrote the solution using a fixed-length string “numbers” instead: day02.c
Still working on the assembly version
Assembly update: have part 1 working now! It’s dog slow on DOSBox, but on QEMU it’s good: day02.asm
Awesome! I was looking for this type of solution and made some progress but couldn’t get to it
Nim
Easy one today. Part 2 is pretty forgiving on performance, so regex bruteforce was only a couple seconds . But eventually I’ve cleaned it up and did a solution that runs in ~340 ms.
type AOCSolution[T,U] = tuple[part1: T, part2: U] proc isRepeating(str:string, sectorLength=1): bool = if str.len mod sectorLength != 0: return false for i in countUp(0, str.len - sectorLength, sectorLength): if str.toOpenArray(i, i+sectorLength-1) != str.toOpenArray(0, sectorLength-1): return false true proc solve(input: string): AOCSolution[int, int] = let ranges = input.split(',').mapIt: let parts = it.split('-') (parseInt parts[0], parseInt parts[1]) for (a, b) in ranges: for num in a .. b: if num < 10: continue let strnum = $num let half = strnum.len div 2 for i in countDown(half, 1): if strnum.isRepeating(i): if i == half and strnum.len mod 2 == 0: result.part1 += num result.part2 += num breakFull solution at Codeberg: solution.nim
DOS + BIOS boot (hybrid binary)

Repo | day02.asm | .COM download
Got the x86-16 assembly implementation working at last! Here, 64-bit integer math, especially lots of divisions by power of 10, wasn’t going to do so the code instead operates on fixed-width, zero-padded numeric strings. Lots of time lost to debugging control flow/logic mistakes this time. I need to make printf() a priority!
Short input so no space issues, sitting comfortably at 45K, well below the 64K COM limit! Sadly no time yet to add animations or anything cool.

