commit aecd7a94862d9b346bfef2e0e247c4b0ec43cd9f
parent 6eaa7994d753e265e3c67e9890db44f5ddbf0ee8
Author: bsandro <brian.drosan@gmail.com>
Date: Sat, 4 Dec 2021 21:40:32 +0200
Day 04, puzzle 1
Diffstat:
5 files changed, 913 insertions(+), 0 deletions(-)
diff --git a/day04/Makefile b/day04/Makefile
@@ -0,0 +1,26 @@
+NAME=$(shell basename ${PWD})
+CC=cc
+SRC=$(wildcard *.c)
+DEPS:=$(wildcard *.h)
+OBJ:=$(SRC:.c=.o)
+
+CFLAGS=-O0 -std=c99 -g -Werror -Wall -Wextra -I.
+
+all: $(NAME)
+
+.PHONY: clean run
+
+clean:
+ rm -f $(OBJ) $(NAME)
+
+%.o : %.c $(DEPS)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+$(NAME): $(OBJ)
+ $(CC) $(OBJ) -o $@ $(LDFLAGS)
+
+run: $(NAME)
+ ./$(NAME) input.txt
+
+test: $(NAME)
+ ./$(NAME) test.txt
diff --git a/day04/input.txt b/day04/input.txt
@@ -0,0 +1,601 @@
+72,86,73,66,37,76,19,40,77,42,48,62,46,3,95,17,97,41,10,14,83,90,12,23,81,98,11,57,13,69,28,63,5,78,79,58,54,67,60,34,39,84,94,29,20,0,24,38,43,51,64,18,27,52,47,74,59,22,85,65,80,2,99,70,33,91,53,93,9,82,8,50,7,56,30,36,89,71,21,49,31,88,26,96,16,1,75,87,6,61,4,68,32,25,55,44,15,45,92,35
+
+58 60 65 4 91
+73 31 80 83 44
+98 47 33 21 25
+76 6 41 94 50
+55 30 52 11 36
+
+ 8 27 21 18 94
+59 3 47 1 64
+67 16 90 20 83
+26 43 87 82 4
+19 93 89 48 72
+
+28 31 21 56 35
+63 98 25 65 61
+46 11 91 24 34
+76 22 15 0 87
+83 80 39 12 71
+
+48 9 95 18 12
+67 20 40 29 51
+ 0 85 21 69 89
+71 81 97 64 13
+75 24 65 50 56
+
+ 1 27 24 93 42
+47 71 21 91 88
+39 7 65 64 51
+28 16 15 25 56
+48 23 32 20 22
+
+26 37 62 13 82
+53 54 16 50 75
+42 18 51 64 60
+25 47 71 38 77
+27 57 29 76 40
+
+97 20 68 90 70
+42 96 62 49 27
+56 67 12 13 94
+71 35 31 54 17
+73 3 5 23 19
+
+43 93 19 7 80
+88 37 51 49 58
+29 97 17 94 65
+61 22 75 98 85
+28 73 84 47 1
+
+96 99 82 7 91
+43 32 48 39 60
+49 51 15 30 11
+16 72 52 69 18
+79 95 41 68 59
+
+90 3 81 44 99
+ 9 40 94 19 37
+41 52 43 83 46
+ 2 42 26 24 70
+49 74 34 66 77
+
+59 83 91 44 0
+62 85 69 18 8
+74 5 94 48 32
+50 46 25 6 96
+87 41 75 22 31
+
+36 61 69 96 87
+77 60 49 32 45
+92 97 34 21 70
+31 62 6 63 2
+56 93 26 54 85
+
+30 96 54 85 82
+29 92 1 74 42
+63 26 65 34 98
+87 91 6 53 64
+62 45 13 50 56
+
+ 3 67 61 56 23
+34 48 39 76 37
+44 83 35 72 29
+70 45 55 47 4
+31 92 6 99 59
+
+ 9 42 99 80 14
+81 57 72 63 18
+19 67 25 90 58
+ 0 4 51 52 69
+93 60 73 28 23
+
+ 5 27 68 24 35
+69 67 49 1 79
+73 64 4 42 32
+55 74 44 90 45
+92 43 33 2 3
+
+ 7 45 24 51 33
+71 66 6 13 23
+77 55 76 48 44
+39 70 43 36 32
+88 5 69 47 92
+
+45 40 5 93 80
+64 37 10 35 4
+11 6 75 30 38
+74 44 26 90 99
+ 1 81 8 50 32
+
+92 71 59 47 32
+45 65 68 55 28
+99 88 17 36 82
+16 22 61 48 93
+29 5 69 24 51
+
+88 85 54 41 92
+10 67 40 4 30
+29 45 32 47 51
+96 81 94 58 34
+39 72 7 46 98
+
+52 33 11 60 69
+19 9 88 93 75
+82 45 72 48 44
+85 61 87 79 26
+71 80 21 0 3
+
+60 1 57 93 81
+17 32 61 21 4
+76 24 46 98 33
+ 9 84 91 6 23
+ 5 59 52 96 54
+
+22 35 20 41 4
+57 8 9 97 10
+19 25 12 65 53
+ 5 50 91 32 23
+58 96 15 7 78
+
+90 78 31 47 88
+81 56 55 95 10
+60 42 68 34 57
+53 64 85 50 35
+48 16 89 93 77
+
+64 4 0 7 16
+58 50 37 98 34
+85 71 75 22 57
+81 91 6 86 19
+61 63 95 40 3
+
+66 88 55 0 32
+68 9 98 73 36
+15 45 39 67 6
+91 11 79 23 84
+12 80 62 14 17
+
+79 31 43 75 97
+54 78 87 60 99
+41 34 32 61 26
+44 37 20 12 18
+16 73 10 71 22
+
+92 83 15 36 27
+28 21 35 42 18
+60 87 41 38 95
+45 10 70 5 80
+11 30 56 17 61
+
+63 25 57 42 14
+24 71 2 11 93
+56 73 16 47 28
+87 64 8 27 83
+21 50 78 48 62
+
+18 29 90 1 16
+39 72 21 88 55
+19 13 69 83 71
+ 7 97 43 58 61
+23 96 9 33 81
+
+36 13 32 1 11
+57 17 91 76 72
+29 83 35 68 90
+87 12 39 19 0
+99 31 16 25 43
+
+ 5 52 64 73 40
+ 0 1 51 3 14
+61 91 55 30 88
+33 83 31 13 71
+24 97 36 19 53
+
+81 15 67 72 78
+20 21 40 96 37
+13 5 33 83 66
+22 61 91 56 84
+35 86 75 41 46
+
+28 29 73 84 26
+42 54 3 15 12
+34 16 62 91 30
+53 13 5 46 55
+67 18 1 59 24
+
+16 39 26 11 67
+36 20 62 27 78
+85 25 9 87 66
+ 6 70 60 98 59
+94 46 17 81 10
+
+35 86 49 59 38
+88 54 68 17 87
+10 9 90 30 62
+82 20 32 77 76
+81 83 79 0 67
+
+26 9 63 23 45
+22 44 36 60 4
+84 91 54 6 78
+94 2 62 61 31
+52 88 42 21 29
+
+ 1 32 44 0 9
+13 36 26 6 17
+50 74 14 51 88
+25 10 73 43 16
+47 68 34 2 81
+
+74 67 38 24 32
+46 53 63 18 82
+33 41 48 90 5
+56 3 20 99 17
+96 94 59 21 87
+
+49 72 39 25 62
+59 99 27 53 98
+33 46 92 38 8
+18 82 90 70 20
+ 3 2 54 0 75
+
+54 34 45 0 19
+95 11 27 62 50
+ 3 77 79 17 81
+74 57 40 83 47
+88 72 39 92 16
+
+65 1 91 71 67
+81 23 34 48 90
+28 92 84 11 3
+ 5 8 61 16 76
+83 46 24 55 82
+
+42 87 55 23 59
+79 54 81 48 95
+61 16 44 13 91
+53 98 72 30 88
+65 69 83 36 64
+
+45 80 47 27 78
+54 36 16 75 1
+17 26 68 28 39
+43 87 49 0 89
+56 24 7 85 92
+
+18 50 95 70 49
+44 47 69 92 54
+96 28 79 67 16
+13 31 29 98 14
+53 20 5 66 25
+
+88 33 27 97 67
+20 69 22 35 0
+50 73 70 52 91
+71 32 48 21 65
+ 3 5 15 30 86
+
+77 85 98 6 11
+15 53 21 89 67
+51 40 62 8 36
+37 69 47 24 29
+39 63 64 72 44
+
+13 7 80 86 29
+45 91 82 41 42
+69 74 12 68 38
+84 51 6 10 14
+57 26 62 17 24
+
+31 88 98 2 11
+33 40 23 30 43
+25 16 50 41 22
+12 51 99 6 89
+91 66 90 97 32
+
+22 74 70 98 54
+25 20 76 40 38
+21 99 69 10 41
+11 59 46 61 36
+87 50 49 84 78
+
+57 25 39 22 86
+37 8 61 78 73
+49 30 95 3 44
+18 1 58 91 46
+24 64 17 13 60
+
+61 10 14 53 83
+32 28 66 65 40
+63 86 48 76 6
+92 69 95 24 55
+59 71 72 30 33
+
+47 76 18 53 56
+37 42 9 28 2
+ 0 80 99 48 27
+79 20 15 5 54
+ 3 7 71 89 87
+
+31 8 16 28 79
+56 77 66 59 36
+ 9 99 85 57 6
+67 82 73 87 91
+37 52 43 58 81
+
+ 9 2 96 51 64
+68 30 36 3 66
+33 57 41 83 52
+90 84 54 20 56
+14 88 62 76 38
+
+17 86 75 54 5
+13 59 68 87 74
+44 62 31 57 98
+ 7 24 36 71 76
+69 23 19 70 73
+
+55 40 1 98 24
+85 29 39 72 3
+80 28 94 67 65
+14 70 49 97 90
+11 2 74 44 48
+
+49 91 63 99 67
+ 1 69 29 22 81
+58 77 62 74 16
+ 9 68 38 6 78
+72 24 94 64 76
+
+94 98 58 41 63
+77 76 73 62 49
+74 38 87 92 46
+83 89 48 5 15
+26 19 8 44 56
+
+72 21 44 61 99
+84 8 66 69 32
+12 38 57 86 37
+87 74 41 3 91
+90 78 45 89 49
+
+22 85 17 59 8
+99 43 79 65 84
+56 36 66 78 57
+50 10 39 67 69
+12 14 34 68 23
+
+ 2 8 58 29 89
+53 54 69 19 48
+22 52 35 36 6
+26 46 44 15 61
+21 71 63 83 99
+
+84 25 24 59 95
+49 29 26 17 58
+39 51 15 72 21
+ 1 13 35 85 11
+ 4 91 18 89 53
+
+49 76 48 58 19
+32 11 53 24 67
+64 12 3 45 31
+ 6 75 44 46 80
+59 90 42 39 83
+
+71 25 59 18 12
+54 10 77 52 13
+42 68 28 17 37
+33 82 47 22 24
+38 14 79 41 84
+
+81 56 34 28 71
+83 27 14 16 30
+63 26 6 45 29
+86 53 60 50 15
+ 8 43 7 44 91
+
+32 30 59 58 55
+76 24 8 79 0
+35 14 46 16 99
+20 19 98 4 94
+74 85 51 31 17
+
+32 37 22 91 52
+ 1 20 88 17 86
+64 61 34 23 79
+28 42 5 67 72
+ 4 94 13 74 14
+
+11 62 72 23 45
+60 65 56 81 29
+83 64 73 61 1
+57 77 2 30 9
+10 39 50 28 88
+
+50 17 65 72 16
+24 86 42 39 68
+20 84 27 98 12
+57 41 1 63 32
+94 22 38 81 18
+
+45 51 38 88 94
+21 24 44 74 63
+29 19 26 57 32
+40 31 56 80 53
+36 70 33 22 93
+
+99 86 22 85 17
+74 45 78 67 39
+18 42 77 46 27
+20 31 40 8 81
+73 47 19 96 15
+
+92 54 10 73 24
+44 18 74 32 19
+69 8 14 46 33
+63 57 97 65 3
+62 34 4 36 35
+
+71 7 5 3 88
+94 79 47 41 28
+51 31 91 23 52
+99 42 39 87 54
+48 59 97 68 4
+
+ 9 93 86 99 26
+14 83 45 43 48
+84 23 17 28 4
+35 79 47 75 61
+54 65 59 81 42
+
+89 99 27 58 96
+23 52 50 24 70
+47 83 61 5 65
+40 19 66 21 0
+55 10 13 81 51
+
+26 30 33 1 57
+41 60 44 96 70
+72 29 24 0 62
+76 69 16 21 93
+52 48 79 84 14
+
+65 36 74 22 80
+21 69 47 31 61
+42 50 92 27 18
+12 24 91 29 6
+28 73 70 76 11
+
+60 79 47 8 30
+65 50 54 56 23
+14 98 33 25 76
+74 71 86 37 66
+72 77 85 39 53
+
+71 56 53 3 19
+88 99 40 61 37
+95 87 8 78 34
+54 75 57 96 12
+50 98 69 58 94
+
+16 9 85 2 87
+88 98 37 13 1
+27 42 15 18 22
+29 58 25 99 72
+38 86 78 91 92
+
+ 3 21 39 81 76
+66 47 80 44 13
+59 2 96 17 62
+35 51 8 37 41
+88 74 14 92 18
+
+71 15 74 60 32
+17 67 69 62 80
+19 1 78 89 85
+22 96 11 8 13
+ 4 86 48 0 61
+
+22 29 68 36 55
+73 62 86 31 90
+ 7 75 49 81 46
+ 9 41 83 67 51
+32 24 59 5 99
+
+84 94 25 18 57
+76 6 98 79 29
+42 10 71 89 5
+74 78 53 85 51
+64 20 49 47 37
+
+95 22 29 37 87
+13 54 0 28 74
+21 50 49 8 92
+81 58 34 2 43
+65 19 63 52 76
+
+15 69 67 23 21
+82 84 20 83 53
+49 59 86 2 31
+71 89 68 40 79
+76 25 42 22 13
+
+82 11 88 77 92
+48 8 61 13 64
+32 72 80 67 3
+52 4 25 75 94
+53 20 33 6 16
+
+41 95 57 46 17
+50 3 99 74 28
+97 39 73 58 70
+75 35 94 51 87
+12 44 43 21 71
+
+74 0 85 48 21
+42 28 16 6 53
+51 25 18 72 47
+83 4 37 79 29
+96 39 78 44 56
+
+45 60 35 49 4
+25 94 68 34 56
+54 17 61 74 50
+70 48 98 5 14
+15 85 21 8 22
+
+29 33 86 96 62
+ 2 43 61 10 46
+11 12 76 31 80
+88 78 37 92 14
+53 57 90 74 1
+
+32 56 43 50 60
+ 0 77 72 51 37
+71 40 69 97 38
+65 2 67 47 81
+54 79 82 84 90
+
+82 26 28 87 93
+61 33 38 89 12
+25 13 5 37 35
+15 67 8 94 16
+95 59 64 41 70
+
+85 22 43 18 13
+64 73 96 16 84
+61 44 12 37 11
+47 35 80 32 14
+ 2 41 60 29 86
+
+52 87 78 6 61
+50 21 54 4 2
+91 1 35 48 72
+99 43 69 44 40
+30 41 19 29 27
+
+10 20 95 69 22
+66 53 77 37 28
+51 89 85 48 21
+16 14 60 73 43
+96 86 12 97 90
+
+48 7 67 47 96
+71 61 60 64 18
+13 15 57 86 93
+46 41 53 88 32
+82 65 26 34 10
+
+80 92 2 54 5
+ 0 17 78 81 43
+33 15 51 73 61
+71 31 47 38 11
+52 29 23 97 14
+
+76 52 54 92 80
+74 50 11 27 78
+63 9 25 38 20
+ 3 90 39 37 15
+87 45 17 93 62
diff --git a/day04/main.c b/day04/main.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+
+int puzzle1(const char *filename);
+//int puzzle2(const char *filename);
+
+int main(int argc, char *argv[]) {
+ printf("Advent of Code: day 04\n");
+
+ if (argc <= 0) {
+ return -1;
+ }
+ if (argc <= 1) {
+ printf("Usage: %s inputfile.txt\n", argv[0]);
+ return -1;
+ }
+
+ const char *filename = argv[1];
+
+ int counter1 = puzzle1(filename);
+ printf("Puzzle #1: %d\n", counter1);
+ //int counter2 = puzzle2(filename);
+ //printf("Puzzle #2: %d\n", counter2);
+
+ return 0;
+}
diff --git a/day04/puzzle1.c b/day04/puzzle1.c
@@ -0,0 +1,242 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <stdbool.h>
+#include <assert.h>
+
+#define PRINT_ERR(func) fprintf(stderr, #func "() error: %s\n", strerror(errno));
+
+#define ARRAY_PUSH
+
+#define FMT_(l) #l
+#define FMT(l) FMT_(l)
+
+#define STR_LEN 16384
+#define FMT_STRING "%" FMT(STR_LEN) "s"
+
+#define BOARD_SIZE 5
+
+struct board_t {
+ int tiles[BOARD_SIZE][BOARD_SIZE]; // 0-99 base, -1 marks drawn tiles
+ int rows_sig[BOARD_SIZE]; // sum of numbers that works as a "signature"
+ int cols_sig[BOARD_SIZE]; // once it goes down to -5 it means r/k are done
+ int sum;
+};
+
+struct array_t {
+ void *data;
+ size_t elem_size;
+ size_t count;
+ size_t cap;
+};
+
+bool array_init(struct array_t *array, size_t elem_size, size_t cap);
+bool array_expand(struct array_t *array);
+
+#define PRINT_ARRAY(array, type) do { \
+ printf("array count %zu, cap %zu, elem size %zu, data %p\n", \
+ array.count, array.cap, array.elem_size, &array); \
+ for (size_t i = 0; i < array.count; ++i) { \
+ type *data = (type *)array.data; \
+ printf("%d ", data[i]); \
+ } \
+ printf("\n"); \
+} while (0);
+
+bool make_numbers_array(struct array_t *numbers, const char *str);
+bool fill_board(struct board_t *board, int row, const char *str);
+
+void print_boards(const struct array_t *boards);
+
+/* ****************************************************************** */
+
+int puzzle1(const char *filename) {
+ FILE *infile = fopen(filename, "r");
+ if (infile == NULL) {
+ fprintf(stderr, "fopen() error: %s\n", strerror(errno));
+ return -1;
+ }
+
+ char buf[STR_LEN] = {0};
+ unsigned int line_num = 0;
+ int result = -1;
+
+ struct array_t numbers = { .data = NULL };
+ struct array_t boards = { .data = NULL };
+
+ if (!array_init(&numbers, sizeof(int), 100)) {
+ fprintf(stderr, "array_init() failed\n");
+ goto finish; // @todo assert?
+ }
+
+ if (!array_init(&boards, sizeof(struct board_t), 10)) {
+ fprintf(stderr, "array_init() failed");
+ goto finish; // @todo assert?
+ }
+
+ struct board_t *current_board = NULL;
+ int current_row = -1;
+
+ while (fgets(buf, STR_LEN, infile) != NULL) {
+ // first line is always random numbers sequence
+ if (line_num == 0) {
+ if (!make_numbers_array(&numbers, buf)) {
+ fprintf(stderr, "make_numbers_array() failed\n");
+ goto finish;
+ }
+
+ } else if (strlen(buf) == 1) { // line sized 1 is a separator before boards
+ if (boards.count >= boards.cap && !array_expand(&boards)) {
+ fprintf(stderr, "array_expand() failed\n");
+ goto finish;
+ }
+
+ struct board_t *data = (struct board_t *)boards.data;
+ current_board = &data[boards.count++];
+ current_row = 0;
+
+ } else { // filling the board
+ assert(current_board != NULL);
+ assert(current_row != -1);
+ if (!fill_board(current_board, current_row++, buf)) {
+ fprintf(stderr, "fill_board() failed\n");
+ goto finish;
+ }
+ }
+
+ ++line_num;
+ bzero(buf, STR_LEN);
+ }
+
+ //print_boards(&boards);
+
+ // rolling
+ for (size_t i = 0; i < numbers.count; ++i) {
+ int num = ((int *)numbers.data)[i];
+
+ for (size_t j = 0; j < boards.count; ++j) {
+ struct board_t *board = &((struct board_t *)boards.data)[j];
+
+ for (int r = 0; r < BOARD_SIZE; ++r) {
+ for (int k = 0; k < BOARD_SIZE; ++k) {
+ if (board->tiles[r][k] == num) {
+ board->tiles[r][k] = -1;
+ board->rows_sig[r] -= num + 1;
+ board->cols_sig[k] -= num + 1;
+ board->sum -= num;
+
+ if (board->rows_sig[r] == -BOARD_SIZE || board->cols_sig[k] == -BOARD_SIZE) {
+ result = board->sum * num;
+ goto out;
+ }
+ }
+ }
+ }
+ }
+ }
+
+out:
+ //print_boards(&boards);
+
+ // mutiny! ignoring feof/ferror.
+finish:
+ free(numbers.data);
+ free(boards.data);
+ fclose(infile);
+ return result;
+}
+
+/* ************************* BOILERPLATE ************************* */
+
+void print_boards(const struct array_t *boards) {
+ for (size_t i = 0; i < boards->count; ++i) {
+ const struct board_t *brd = (const struct board_t *)boards->data;
+ brd += i;
+ printf("\n----------- board %2zu ------------\n", i);
+ for (int r = 0; r < BOARD_SIZE; ++r) {
+ for (int k = 0; k < BOARD_SIZE; ++k) {
+ printf("[%3d]", brd->tiles[r][k]);
+ }
+ printf(" = [%3d]\n", brd->rows_sig[r]);
+ }
+ printf("=================================\n");
+ for (int k = 0; k < BOARD_SIZE; ++k) {
+ printf("[%3d]", brd->cols_sig[k]);
+ }
+ printf("\n");
+ }
+}
+
+bool make_numbers_array(struct array_t *numbers, const char *str) {
+ char *tmp = strndup(str, STR_LEN);
+ char *token = NULL;
+
+ assert(tmp != NULL);
+
+ while ((token = strsep(&tmp, ",")) != NULL) {
+ int num = atoi(token);
+
+ if (numbers->count >= numbers->cap && !array_expand(numbers)) {
+ fprintf(stderr, "array_expand() failed\n");
+ return false;
+ }
+
+ int *data = (int *)numbers->data;
+ data[numbers->count++] = num;
+ }
+
+ free(tmp);
+ return true;
+}
+
+bool fill_board(struct board_t *board, int row, const char *str) {
+ char *tmp = strndup(str, STR_LEN);
+ assert(tmp != NULL);
+ char *token = NULL;
+ int col = 0;
+ while ((token = strsep(&tmp, " ")) != NULL) {
+ if (*token != '\0') { // WOWZA
+ int num = atoi(token);
+ board->tiles[row][col] = num;
+ board->rows_sig[row] += num;
+ board->cols_sig[col] += num;
+ board->sum += num;
+ ++col;
+ }
+ }
+ assert(col == BOARD_SIZE);
+ return true;
+}
+
+// @todo move generic service stuff to some kind of shared header?
+
+bool array_init(struct array_t *array, size_t elem_size, size_t cap) {
+ if (array->data != NULL)
+ return false;
+
+ array->cap = cap;
+ array->elem_size = elem_size;
+ array->data = calloc(cap, elem_size);
+
+ if (array->data == NULL) {
+ PRINT_ERR(calloc)
+ return false;
+ }
+
+ return true;
+}
+
+bool array_expand(struct array_t *array) {
+ size_t new_cap = array->cap * 2;
+ array->data = realloc(array->data, array->elem_size * new_cap);
+
+ if (array->data == NULL) {
+ PRINT_ERR(realloc)
+ return false;
+ }
+
+ array->cap = new_cap;
+ return true;
+}
diff --git a/day04/test.txt b/day04/test.txt
@@ -0,0 +1,19 @@
+7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
+
+22 13 17 11 0
+ 8 2 23 4 24
+21 9 14 16 7
+ 6 10 3 18 5
+ 1 12 20 15 19
+
+ 3 15 0 2 22
+ 9 18 13 17 5
+19 8 7 25 23
+20 11 10 24 4
+14 21 16 12 6
+
+14 21 17 24 4
+10 16 15 9 19
+18 8 23 26 20
+22 11 13 6 5
+ 2 0 12 3 7