advent2021

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

commit 28bc5515d589db4d76490959f10e62829500a151
parent 89dd052fa8e070981bfa36845678dde85112f7eb
Author: bsandro <brian.drosan@gmail.com>
Date:   Wed,  8 Dec 2021 02:15:49 +0200

Day 03 refactoring

Diffstat:
Mday03/Makefile | 6+++---
Mday03/puzzle2.c | 106++++++++++++++++++++++++++++---------------------------------------------------
2 files changed, 40 insertions(+), 72 deletions(-)

diff --git a/day03/Makefile b/day03/Makefile @@ -1,10 +1,10 @@ NAME=$(shell basename ${PWD}) CC=cc -SRC=$(wildcard *.c) -DEPS:=$(wildcard *.h) +SRC=$(wildcard *.c ../common/*.c) +DEPS:=$(wildcard *.h ../common/*.h) OBJ:=$(SRC:.c=.o) -CFLAGS=-O0 -std=c99 -g -Werror -Wall -Wextra -I. +CFLAGS=-O0 -std=c99 -g -Werror -Wall -Wextra -I. -I../common all: $(NAME) diff --git a/day03/puzzle2.c b/day03/puzzle2.c @@ -5,27 +5,18 @@ #include <strings.h> #include <stdbool.h> #include <sys/stat.h> +#include <assert.h> -#define PRINT_ERR(func) fprintf(stderr, #func "() error: %s\n", strerror(errno)); - -#define FMT_(l) #l -#define FMT(l) FMT_(l) +#include "util.h" #define MAX_LEN 16 #define BITS_COUNT 12 #define STR_LEN 13 // BITS_COUNT + 1 (EOL/EOF or terminating byte) #define FMT_STRING "%" FMT(STR_LEN) "s" -struct numbers_t { - long *data; - size_t limit; - size_t count; -}; - -bool init_numbers(struct numbers_t *numbers, size_t limit); -bool copy_numbers(const struct numbers_t *src, struct numbers_t *dst); -void move_numbers(struct numbers_t *src, struct numbers_t *dst); -bool filter_numbers_by_bit(struct numbers_t *numbers, int bit_num, bool (cmp)(size_t, size_t)); +bool copy_numbers(const struct array_t *src, struct array_t *dst); +void move_numbers(struct array_t *src, struct array_t *dst); +bool filter_numbers_by_bit(struct array_t *numbers, int bit_num, bool (cmp)(size_t, size_t)); bool compare_oxygen(size_t zeroes, size_t ones) { return zeroes > ones; @@ -42,8 +33,7 @@ int puzzle2(const char *filename) { return -1; } - struct numbers_t numbers; - init_numbers(&numbers, 0); + struct array_t numbers = { .data = NULL }; // deducing the approx numbers array size from the filesize struct stat filestats = {0}; @@ -51,12 +41,8 @@ int puzzle2(const char *filename) { PRINT_ERR(stat) return -1; } else { - numbers.limit = filestats.st_size / STR_LEN; - numbers.data = calloc(numbers.limit, sizeof(long)); - if (numbers.data == NULL) { - PRINT_ERR(calloc) - return -1; - } + array_init(&numbers, sizeof(long), filestats.st_size / STR_LEN); + assert(numbers.data != NULL); } char buf[MAX_LEN] = {0}; @@ -65,16 +51,11 @@ int puzzle2(const char *filename) { while (fgets(buf, MAX_LEN, infile) != NULL) { if (sscanf(buf, FMT_STRING, str) == 1) { // just a precaution, good 'ole "allocate x2 if it doesn't fit anymore" - if (numbers.count >= numbers.limit) { - numbers.limit *= 2; - numbers.data = realloc(numbers.data, numbers.limit * sizeof(long)); - if (numbers.data == NULL) { - free(numbers.data); - PRINT_ERR(realloc) - return -1; - } + if (numbers.count >= numbers.cap) { + array_expand(&numbers); } - numbers.data[numbers.count++] = strtol(str, NULL, 2); + long *data = (long *)numbers.data; + data[numbers.count++] = strtol(str, NULL, 2); bzero(buf, MAX_LEN); bzero(str, STR_LEN); } @@ -82,10 +63,10 @@ int puzzle2(const char *filename) { long oxygen_number = 0; long scrubber_number = 0; - struct numbers_t oxygen; - struct numbers_t scrubber; - init_numbers(&oxygen, 0); - init_numbers(&scrubber, 0); + struct array_t oxygen = { .data = NULL }; + struct array_t scrubber = { .data = NULL }; + array_init(&oxygen, numbers.elem_size, 10); + array_init(&scrubber, numbers.elem_size, 10); if (!copy_numbers(&numbers, &oxygen) || !copy_numbers(&numbers, &scrubber)) { fprintf(stderr, "copy_numbers() error\n"); return false; @@ -101,8 +82,8 @@ int puzzle2(const char *filename) { goto finish; } - oxygen_number = oxygen.data[0]; - scrubber_number = scrubber.data[0]; + oxygen_number = ((long *)oxygen.data)[0]; + scrubber_number = ((long *)scrubber.data)[0]; // mutiny! ignoring feof/ferror. finish: @@ -114,59 +95,46 @@ finish: return oxygen_number * scrubber_number; } -bool init_numbers(struct numbers_t *numbers, size_t limit) { - numbers->data = NULL; - numbers->count = 0; - numbers->limit = limit; - - if (limit > 0) { - numbers->data = calloc(limit, sizeof(long)); - if (numbers->data == NULL) { - PRINT_ERR(calloc) - return false; - } - } - - return true; -} - -bool copy_numbers(const struct numbers_t *src, struct numbers_t *dst) { - if (src->data == NULL || src->count == 0 || src->limit == 0) +bool copy_numbers(const struct array_t *src, struct array_t *dst) { + if (src->data == NULL || src->count == 0 || src->cap == 0) return false; - size_t dst_size = src->count * sizeof(long); + size_t dst_size = src->count * src->elem_size; dst->data = realloc(dst->data, dst_size); dst->count = src->count; - dst->limit = src->limit; + dst->cap = src->cap; memcpy(dst->data, src->data, dst_size); return true; } -void move_numbers(struct numbers_t *src, struct numbers_t *dst) { +void move_numbers(struct array_t *src, struct array_t *dst) { free(dst->data); dst->data = src->data; dst->count = src->count; - dst->limit = src->limit; + dst->cap = src->cap; } -bool filter_numbers_by_bit(struct numbers_t *numbers, int bit_num, bool (cmp)(size_t, size_t)) { +bool filter_numbers_by_bit(struct array_t *numbers, int bit_num, bool (cmp)(size_t, size_t)) { if (numbers->count == 1) return false; - struct numbers_t filtered_0; - if (!init_numbers(&filtered_0, numbers->count)) - return false; + struct array_t filtered_0 = { .data = NULL }; + array_init(&filtered_0, numbers->elem_size, numbers->count); + assert(filtered_0.data != NULL); - struct numbers_t filtered_1; - if (!init_numbers(&filtered_1, numbers->count)) - return false; + struct array_t filtered_1 = { .data = NULL }; + array_init(&filtered_1, numbers->elem_size, numbers->count); + assert(filtered_1.data != NULL); + long *data = numbers->data; + long *f0_data = filtered_0.data; + long *f1_data = filtered_1.data; for (size_t i = 0; i < numbers->count; ++i) { - if (numbers->data[i] & (1 << bit_num)) { - filtered_1.data[filtered_1.count++] = numbers->data[i]; + if (data[i] & (1 << bit_num)) { + f1_data[filtered_1.count++] = data[i]; } else { - filtered_0.data[filtered_0.count++] = numbers->data[i]; + f0_data[filtered_0.count++] = data[i]; } }