C
Interestingly part 1 already defied a naive approach. It was fun thinking of a way to memoize without hash tables.
Code
#include "common.h"
static char *pats[480];
static int lens[480];
int np;
/* memoized for 's' by mem[off], 0 = unknown, >0 = value+1 */
static int64_t
recur(char *s, int off, int64_t *mem)
{
int64_t acc=0;
int i;
if (!s[off]) return 1;
if (mem[off]) return mem[off]-1;
for (i=0; i<np; i++)
if (!strncmp(s+off, pats[i], lens[i]))
acc += recur(s, off+lens[i], mem);
mem[off] = acc+1;
return acc;
}
int
main(int argc, char **argv)
{
static char patbuf[3200], design[64];
int64_t p1=0,p2=0, mem[64], n;
char *rest, *lf;
if (argc > 1)
DISCARD(freopen(argv[1], "r", stdin));
rest = fgets(patbuf, sizeof(patbuf), stdin);
for (; (pats[np] = strsep(&rest, ",")); np++) {
while (isspace(pats[np][0]))
pats[np]++; /* skip spaces */
if ((lf = strchr(pats[np], '\n')))
*lf = '\0'; /* trim trailing \n */
lens[np] = strlen(pats[np]);
assert(np+1 < (int)LEN(pats));
}
while (scanf(" %63s", design) == 1) {
memset(mem, 0, sizeof(mem));
n = recur(design, 0, mem);
p1 += n >0;
p2 += n;
}
printf("19: %"PRId64" %"PRId64"\n", p1, p2);
return 0;
}
https://codeberg.org/sjmulder/aoc/src/branch/master/2024/c/day19.c
Zee
Also a port to my cursed Dutch dialect of C, Zee:
Code
#ingesloten "zee.kop"
#ingesloten "algemeen.kop"
besloten letterverwijzing patronen[480];
besloten getal lengtes[480];
getal patroonsom;
besloten zeer groot getal
afdaling(
letterverwijzing tekst,
getal startpositie,
zeergrootgetalreeksverwijzing onthouden)
{
zeer groot getal deelsom=0;
getal sortering, teller;
tenzij (tekst[startpositie])
lever 1;
mits (onthouden[startpositie])
lever onthouden[startpositie]-1;
voor (teller=0; teller < patroonsom; teller++) {
sortering = tekstdeelvergelijking(
tekst + startpositie,
patronen[teller],
lengtes[teller]);
mits (sortering == 0) {
deelsom += afdaling(
tekst,
startpositie + lengtes[teller],
onthouden);
}
}
onthouden[startpositie] = deelsom+1;
lever deelsom;
}
getal
aanvang(
getal parametersom,
letterverwijzingsreeksverwijzing parameters)
{
blijvende letter patroonruimte[3200];
blijvende letter ontwerp[64];
zeer groot getal deel1=0, aantal;
zeer groot getal deel2=0, onthouden[64];
letterverwijzing rest;
letterverwijzing regeleinde;
mits (parametersom > 1)
VERWERP(heropen(parameters[1], "r", standaardinvoer));
rest = geefregel(patroonruimte, grootte(patroonruimte),
standaardinvoer);
voor (; ; patroonsom++) {
verzeker(patroonsom+1 < (getal)LENGTE(patronen));
patronen[patroonsom] = tekstsplitsing(naar rest, ",");
mits (patronen[patroonsom] == NIETS)
klaar;
zolang (iswitruimte(patronen[patroonsom][0]))
patronen[patroonsom]++;
mits ((regeleinde = zoekletter(patronen[patroonsom], '\n')))
volg regeleinde = '\0';
lengtes[patroonsom] = tekstlengte(patronen[patroonsom]);
}
zolang (invorm(" %63s", ontwerp) == 1) {
overschrijf(onthouden, 0, grootte(onthouden));
aantal = afdaling(ontwerp, 0, onthouden);
deel1 += aantal >0;
deel2 += aantal;
}
uitvorm("19: %"GEEFZGG" %"GEEFZGG"\n", deel1, deel2);
lever 0;
}
Awesome! I understood the idea behind the binary search but thought it wasn't a good fit for the flood fill. As opposed to something like A* it will give you reachability and cost for every cell (at a cost), but that's no use when you do repeated searches that are only meant to find a single path. So I was very happy with your suggestion, it fits better with the strengths.
"Virtually instant" btw is measured 0.00 by
time
. I like it when things are fast but I also prefer simper approaches (that is: loops and arrays) over the really optimized fast stuff. People do really amazing things but the really clever algorithms lean on optimized generic data structures that C lacks. It's fun though to see how far you can drive loops and arrays! Perhaps next year I'll pick a compiled language with a rich data structure library and really focus on effectively applying good algorithms and appropriate data structures.Btw how do you measure performance? I see a lot of people including timing things in their programs but I can't be bothered. Some people also exclude parsing - which wouldn't work for me because I try to process the input immediately, if possible.