

C
Sweet one. Glad the merge could be done with one n2/2 scan and no sorting or moving, which will make the assembly port a bit easier. Speaking of which, I’m still at day 3 there, fighting not the puzzles but the 64K .COM file limit!
Code
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#define MR 256
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
struct range { uint64_t lo, hi; };
static struct range rs[MR];
static int nrs;
int
main()
{
uint64_t p1=0,p2=0, val;
int i,j;
char buf[64];
for (; fgets(buf, sizeof(buf), stdin); nrs++) {
assert(nrs < MR);
if (sscanf(buf, "%lu-%lu", &rs[nrs].lo, &rs[nrs].hi) != 2)
break;
}
for (i=0; i<nrs-1; i++)
for (j=i+1; j<nrs; j++)
if (rs[i].lo <= rs[j].hi && rs[i].hi >= rs[j].lo) {
rs[j].lo = MIN(rs[i].lo, rs[j].lo);
rs[j].hi = MAX(rs[i].hi, rs[j].hi);
rs[i].lo = rs[i].hi = 0;
}
while (scanf("%lu", &val) == 1)
for (i=0; i<nrs; i++)
if (val >= rs[i].lo && val <= rs[i].hi)
{ p1++; break; }
for (i=0; i<nrs; i++)
if (rs[i].lo)
p2 += rs[i].hi - rs[i].lo + 1;
printf("05: %lu %lu\n", p1, p2);
}










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