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

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 2 points 10 months ago

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);
}

  • source