Day 6: Trash Compactor
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
Well so much for reading a grid of ints in part 1! For part 2, initially I reworked the parsing to read into a big buffer, but then thought it would be fun to try and use memory-mapped I/O as not to use any more memory than strictly necessary for the final version:
Code
#include <stdio.h> #include <stdlib.h> #include <inttypes.h> #include <ctype.h> #include <assert.h> #include <sys/mman.h> #include <unistd.h> #include <err.h> #define GH 5 int main() { char *data, *g[GH], *p; uint64_t p1=0,p2=0, acc; int len, h=0, i, x,y, val; char op; if ((len = (int)lseek(0, 0, SEEK_END)) == -1) err(1, "<stdin>"); if (!(data = mmap(NULL, len, PROT_READ, MAP_SHARED, 0, 0))) err(1, "<stdin>"); for (i=0; i<len; i++) if (!i || data[i-1]=='\n') { assert(h < GH); g[h++] = data+i; } for (x=0; g[h-1]+x < data+len; x++) { if ((op = g[h-1][x]) != '+' && op != '*') continue; for (acc = op=='*', y=0; y<h-1; y++) { val = atoi(&g[y][x]); acc = op=='+' ? acc+val : acc*val; } p1 += acc; for (acc = op=='*', i=0; ; i++) { for (val=0, y=0; y<h-1; y++) { p = &g[y][x+i]; if (p < g[y+1] && isdigit(*p)) val = val*10 + *p-'0'; } if (!val) break; acc = op=='+' ? acc+val : acc*val; } p2 += acc; } printf("06: %"PRIu64" %"PRIu64"\n", p1, p2); }