Day 7: Laboratories ## 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
You must log in or register to comment.
Nim
Another simple one.
Part 1: count each time a beam crosses a splitter.
Part 2: keep count of how many particles are in each column in all universes
(e.g. with a simple 1d array), then sum.Runtime:
116 μs95 µs86 µsold version
type AOCSolution[T,U] = tuple[part1: T, part2: U] proc solve(input: string): AOCSolution[int, int] = var beams = newSeq[int](input.find '\n') beams[input.find 'S'] = 1 for line in input.splitLines(): var newBeams = newSeq[int](beams.len) for pos, cnt in beams: if cnt == 0: continue if line[pos] == '^': newBeams[pos-1] += cnt newBeams[pos+1] += cnt inc result.part1 else: newbeams[pos] += cnt beams = newBeams result.part2 = beams.sum()Update: found even smaller and faster version that only needs a single array.
Update #2: small optimizationtype AOCSolution[T,U] = tuple[part1: T, part2: U] proc solve(input: string): AOCSolution[int, int] = var beams = newSeq[int](input.find '\n') beams[input.find 'S'] = 1 for line in input.splitLines(): for pos, c in line: if c == '^' and beams[pos] > 0: inc result.part1 beams[pos-1] += beams[pos] beams[pos+1] += beams[pos] beams[pos] = 0 result.part2 = beams.sum()Full solution at Codeberg: solution.nim
C
Accidentally solved part 2 first but had the foresight to save the code. Otherwise my solution looks similar to what other people are doing, just with more code 😅
Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> #include <assert.h> #define GW 148 #define GH 74 static char g[GH][GW]; static uint64_t dp[2][GW]; static int w,h; /* recursively traces beam for part 1, marking visited splitters with 'X' */ static uint64_t solve_p1(int x, int y) { if (x<0 || x>=w || y<0 || y>=h || g[y][x] == 'X') return 0; else if (g[y][x] != '^') return solve_p1(x, y+1); else { g[y][x] = 'X'; return 1 + solve_p1(x-1, y) + solve_p1(x+1, y); } } /* DP for part 2 */ static uint64_t solve_p2(void) { int x,y, odd; for (y=h-1; y>=0; y--) for (x=1; x<w-1; x++) { /* only two rows relevant at a time, so don't store any more */ odd = y&1; if (g[y][x] == 'S') { printf("\n"); return dp[!odd][x] + 1; } dp[odd][x] = g[y][x] == '^' || g[y][x] == 'X' ? dp[!odd][x-1] + dp[!odd][x+1] + 1 : dp[!odd][x]; } return 0; } int main() { int x,y, sx,sy; for (h=0; ; ) { /* one bottom row of padding */ assert(h < GH-1); /* input already side padded, plus we have \n\0 */ if (!fgets(g[h], GW, stdin)) break; /* skip empty rows */ for (x=0; g[h][x]; x++) if (g[h][x] == 'S' || g[h][x] == '^') { h++; break; } } w = strlen(g[0])-1; /* strip \n */ for (y=0; y<h; y++) for (x=0; x<w; x++) if (g[y][x] == 'S') { sx=x; sy=y; break; } printf("07: %"PRIu64" %"PRIu64"\n", solve_p1(sx,sy), solve_p2()); }Ahh I knew there would be some simple combined representation like this but couldn’t be bothered. Nice!

