commit e9d25d8ce8565f3cdccb91b8471c5d9f09fd5459
parent 29117a3e835db21029e19364b4aa055f8b413394
Author: bsandro <[email protected]>
Date: Tue, 7 Dec 2021 00:20:08 +0200
Day 06, puzzle 2 (complete rewrite of puzzle 1 as well)
Diffstat:
4 files changed, 49 insertions(+), 89 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1 +1,2 @@
*.o
+.DS_Store
diff --git a/day06/Makefile b/day06/Makefile
@@ -4,7 +4,7 @@ SRC=$(wildcard *.c)
DEPS:=$(wildcard *.h)
OBJ:=$(SRC:.c=.o)
-CFLAGS=-O2 -std=c99 -Werror -Wall -Wextra -I. -I../common
+CFLAGS=-Os -std=c99 -Werror -Wall -Wextra -I. -I../common
all: $(NAME)
diff --git a/day06/main.c b/day06/main.c
@@ -1,7 +1,7 @@
#include <stdio.h>
#include <time.h>
-void puzzle(const char *filename, int *res1, int *res2);
+void puzzle(const char *filename, size_t *res1, size_t *res2);
int main(int argc, char *argv[]) {
printf("Advent of Code: day 06\n");
@@ -17,13 +17,13 @@ int main(int argc, char *argv[]) {
const char *filename = argv[1];
- int counter1 = -1;
- int counter2 = -1;
+ size_t counter1 = -1;
+ size_t counter2 = -1;
puzzle(filename, &counter1, &counter2);
- printf("Puzzle #1: %d\n", counter1);
- printf("Puzzle #2: %d\n", counter2);
+ printf("Puzzle #1: %zu\n", counter1);
+ printf("Puzzle #2: %zu\n", counter2);
double elapsed = clock() - time_start;
printf("Elapsed: %f\n", elapsed / CLOCKS_PER_SEC);
diff --git a/day06/puzzle.c b/day06/puzzle.c
@@ -9,30 +9,17 @@
#include <assert.h>
#include <time.h>
-#define STR_LEN 16384
-#define DAYS 80
-#define KODOMO 8
-#define OYAKO 6
-
-struct fish_t {
- struct fish_t *next;
- int value;
-} fish_t;
-
-struct fishes_list_t {
- struct fish_t *first;
- struct fish_t *last;
- size_t size;
-};
-
-void make_fishes_list(struct fishes_list_t *fishes, const char *str);
-void print_fishes_list(struct fishes_list_t *fishes);
-void add_fish(struct fishes_list_t *fishes, int value);
-struct fish_t * new_fish(int value);
+#define STR_LEN 16384
+#define FISH_VARIANTS 8
+#define FISHES_SIZE 9
+#define FISH_COMMON 6
+
+void make_fishes(size_t *fishes, const char *str);
+size_t sum_fishes(size_t *orig_fishes, int days);
/* ****************************************************************** */
-void puzzle(const char *filename, int *result1, int *result2) {
+void puzzle(const char *filename, size_t *result1, size_t *result2) {
FILE *infile = fopen(filename, "r");
if (infile == NULL) {
fprintf(stderr, "fopen() error: %s\n", strerror(errno));
@@ -42,70 +29,22 @@ void puzzle(const char *filename, int *result1, int *result2) {
char buf[STR_LEN] = {0};
unsigned int line_num = 0;
- *result1 = 0;
- *result2 = 0;
-
- struct fishes_list_t fishes = { .first = NULL, .last = NULL, .size = 0};
+ size_t fishes[FISHES_SIZE] = {0};
while (fgets(buf, STR_LEN, infile) != NULL) {
- make_fishes_list(&fishes, buf);
-
+ make_fishes(fishes, buf);
++line_num;
bzero(buf, STR_LEN);
}
- //printf("fishes:");
- //print_fishes_list(&fishes);
- struct fish_t *fish = NULL;
-
- for (int day = 1; day <= DAYS; ++day) {
- fish = fishes.first;
- size_t num = 0;
- size_t cnt = fishes.size;
- while (fish != NULL && num < cnt) {
- if (fish->value == 0) {
- add_fish(&fishes, KODOMO);
- fish->value = OYAKO;
- } else {
- fish->value--;
- }
- fish = fish->next;
- num++;
- }
- //printf("day %2d: %zu\n", day, fishes.size);
- //print_fishes_list(&fishes);
- }
-
- *result1 = fishes.size;
+ *result1 = sum_fishes(fishes, 80);
+ *result2 = sum_fishes(fishes, 256);
// mutiny! ignoring feof/ferror.
fclose(infile);
}
-struct fish_t * new_fish(int value) {
- struct fish_t *fish = malloc(sizeof(struct fish_t));
- assert(fish != NULL);
- fish->value = value;
- fish->next = NULL;
- return fish;
-}
-
-void add_fish(struct fishes_list_t *fishes, int value) {
- struct fish_t *fish = new_fish(value);
- if (fishes->first == NULL) {
- fishes->first = fish;
- }
-
- if (fishes->last == NULL) {
- fishes->last = fish;
- }
-
- fishes->last->next = fish;
- fishes->last = fish;
- ++fishes->size;
-}
-
-void make_fishes_list(struct fishes_list_t *fishes, const char *str) {
+void make_fishes(size_t *fishes, const char *str) {
assert(fishes != NULL);
assert(str != NULL);
char *tmp = strndup(str, STR_LEN);
@@ -114,19 +53,39 @@ void make_fishes_list(struct fishes_list_t *fishes, const char *str) {
while ((token = strsep(&tmp, ",")) != NULL) {
int val = atoi(token);
- add_fish(fishes, val);
+ assert(val < FISH_VARIANTS);
+ fishes[val]++;
}
free(tmp);
}
-void print_fishes_list(struct fishes_list_t *fishes) {
- assert(fishes != NULL);
- assert(fishes->first != NULL);
- struct fish_t *fish = fishes->first;
- while (fish != NULL) {
- printf("%2d", fish->value);
- fish = fish->next;
+size_t sum_fishes(size_t *orig_fishes, int days) {
+ assert(orig_fishes != NULL);
+ size_t fishes[FISHES_SIZE];
+ memcpy(fishes, orig_fishes, sizeof(size_t) * FISHES_SIZE);
+
+ for (int day = 1; day <= days; ++day) {
+ // took me an eternity to see the pattern
+ // thanks for help from friends from the #lobsters-advent
+ // fixed it without using matrices multiplication
+
+ // [a, b, c, d, e, f, g, h, i] -> [b, c, d, e, f, g, h+a, i, a]
+ size_t fish_0 = fishes[0];
+ for (int i = 0; i < FISH_VARIANTS; ++i) {
+ if (i == FISH_COMMON) {
+ fishes[i] = fishes[i+1] + fish_0;
+ } else {
+ fishes[i] = fishes[i+1];
+ }
+ }
+ fishes[FISH_VARIANTS] = fish_0;
}
- printf("\n");
+
+ size_t result = 0;
+ for (int i = 0; i < FISHES_SIZE; ++i) {
+ result += fishes[i];
+ }
+
+ return result;
}