aoc

Advent of Code Solutions
git clone git://git.alexkarle.com.com/aoc
Log | Files | Refs | README | LICENSE

commit 3c39a9143cad06f3e05d3c7478d8313380003361 (patch)
parent 7e1f3d0f3d281d19fe34d714b4838f9aa8206821
Author: Alex Karle <alex@alexkarle.com>
Date:   Mon,  6 Dec 2021 00:59:24 -0500

day6: Add hyper-optimized C solution

Ok, so the parser was a huge struggle here and I was *reallllly* tempted
to just rewrite the `input` to be split on newlines (using sed)... but I
figured part of the "learning" is learning how to tokenize strings in C
and not relying on existing tools...

Other hiccups:

* b required the use of long longs due to overflow
* it took FOREVER to realize that despite fish aging to the '6th' index,
  I really needed them to age to the 7th which is the 6th on the next
  iteration...

Diffstat:
A6/a.c | 37+++++++++++++++++++++++++++++++++++++
A6/b.c | 39+++++++++++++++++++++++++++++++++++++++
MMakefile | 2+-
3 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/6/a.c b/6/a.c @@ -0,0 +1,37 @@ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +int main(void) { + int counts[9] = {0}; + + /* Wow, the parser is more complex than the algorithm :( */ + char *line = NULL; + size_t linesize = 0; + getline(&line, &linesize, stdin); + char *p; + for (p = strtok(line, ","); p; p = strtok(NULL, ",")) { + counts[atoi(p)]++; + } + free(line); + + /* Phew, made it */ + for (int i = 0; i < 80; i++) { + /* Rather than pop & append, just edit in place and rotate + * the start index in use; i.e. on day 2, idx 1 is '0'. + * + * In fact, really all we need to do is add the current + * "populating fish" (mod 0) to the 7th index (which will + * be the 6th index on the next "lifecycle". + * */ + counts[(i + 7) % 9] += counts[i % 9]; + } + + int sum = 0; + for (int i = 0; i < 9; i++) { + sum += counts[i]; + } + printf("%d\n", sum); + + return 0; +} diff --git a/6/b.c b/6/b.c @@ -0,0 +1,39 @@ +/* NOTE: only diff from a.c is the 256 rotation and use of a long long for + * big vals (tm). Duplicated for the sake of the build system :) */ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +int main(void) { + unsigned long long counts[9] = {0}; + + /* Wow, the parser is more complex than the algorithm :( */ + char *line = NULL; + size_t linesize = 0; + getline(&line, &linesize, stdin); + char *p; + for (p = strtok(line, ","); p; p = strtok(NULL, ",")) { + counts[atoi(p)]++; + } + free(line); + + /* Phew, made it */ + for (int i = 0; i < 256; i++) { + /* Rather than pop & append, just edit in place and rotate + * the start index in use; i.e. on day 2, idx 1 is '0'. + * + * In fact, really all we need to do is add the current + * "populating fish" (mod 0) to the 7th index (which will + * be the 6th index on the next "lifecycle". + * */ + counts[(i + 7) % 9] += counts[i % 9]; + } + + unsigned long long sum = 0; + for (int i = 0; i < 9; i++) { + sum += counts[i]; + } + printf("%llu\n", sum); + + return 0; +} diff --git a/Makefile b/Makefile @@ -11,7 +11,7 @@ CFLAGS = -g -O2 -Wall -Wpedantic -Wextra DAY = * -TARGETS = 1/a 1/b 2/a 2/b 3/a 5/a 5/b +TARGETS = 1/a 1/b 2/a 2/b 3/a 5/a 5/b 6/a 6/b .PHONY: build build: $(TARGETS)