advent2021

Advent of Code 2021 Solutions
git clone git://bsandro.tech/advent2021
Log | Files | Refs

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:
M.gitignore | 1+
Mday06/Makefile | 2+-
Mday06/main.c | 10+++++-----
Mday06/puzzle.c | 125+++++++++++++++++++++++++++----------------------------------------------------
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; }