commit c264ecb29c6f47ba1fb60a17914a2ba8958c7fd1
parent 35c67ee884ea91515df3545b91677acfd48b4f2c
Author: bsandro <[email protected]>
Date: Tue, 21 Dec 2021 04:08:00 +0200
Day 20, puzzles 1 and 2
Diffstat:
6 files changed, 374 insertions(+), 0 deletions(-)
diff --git a/day20/Makefile b/day20/Makefile
@@ -0,0 +1,25 @@
+NAME=$(shell basename ${PWD})
+SRC=$(wildcard *.c ../common/*.c)
+DEPS:=$(wildcard *.h ../common/*.h)
+OBJ:=$(SRC:.c=.o)
+CFLAGS=-O2 -std=c99 -Werror -Wall -Wextra -I. -I../common
+LDFLAGS=-lc
+
+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/day20/Makefile.debug b/day20/Makefile.debug
@@ -0,0 +1,25 @@
+NAME=$(shell basename ${PWD})
+SRC=$(wildcard *.c ../common/*.c)
+DEPS:=$(wildcard *.h ../common/*.h)
+OBJ:=$(SRC:.c=.o)
+CFLAGS=-O0 -g -fsanitize=address -fno-omit-frame-pointer -std=c99 -Werror -Wall -Wextra -I. -I../common
+LDFLAGS=-g -lc -fsanitize=address
+
+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/day20/input.txt b/day20/input.txt
@@ -0,0 +1,102 @@
+########..#..#.##.##.#.#..#.#.###.######.##..##.##..#...#....##.##...##.#.#...#.#.##.###.#.##.#.##.#...#.#.###.#.##.#.####.###..#.####.##..#.#####..####.#.#.#....##.#.#.##...#.####.#....#.##..##...#...#.##..#...#.#..#..#.#.#..##..#.##.##..##...#..###...##..#..###.###.##..#..#####...#.#..###..##....##...#####.#####...##.#.##.#....#.##.#.###.#.##.#.##...######.#...##.#..#.#.#...###.#..#.##.####..##.#..#.##.#.##.######.#.....#.#....####.####.###...#....#..###..###.#...#.#.#.##..#..##.#.#..#..###.#.###..#......
+
+##..##.#.#.###.##...##..#...#..##...##.#.####.##..#.#.##.###.#.#...#.#.....#.#..##.#.########....##.
+#.#.#.###..###.#..#.#...#..#....#.....#.##.#.#..#####.##.###.#...#...#.#.##.#...##.###..#..##.#.###.
+.####......#..#..##..#.##..##.#####.##.#...#.#.#.#.#.#.#.####.#....##...#....##..####...####.#.###..
+##.#....###.###.###..###..##.###..#.#####..#..#.#..#.#..#.####..##.#..#..##...##.##.##.##.##....#.##
+.#..####..#####.##...#.#.#..###.#.##...#...#..##.##.#.##..#....#.#.#....##.#.....#########.#.###....
+.######..#....#.#....##...#..#.#######.....#..#....###.##.#.##.#...#.####..####..######..#....#..###
+..######...#....###.##..#.#.#.####..#...##.###..##.###.#..#.#######...#....####.########.#.##..###..
+#.#.####...#.#.##.#..#..###.......#.....##.#..#.###.#..#.#.#.#.##.###.#..##..#.#...##..###...#..#..#
+#####.#####...#.....##......#...###..###..#.#.#.####.##.#.##...#.#.##.#.###.....#........###....#...
+.#..###.#...#.###...#.##..#.##...#####.####.##.#.#.###..##.##....#..#...#..#..##.#.#.#.#.....##.#..#
+..#.####.#...###...###..#..#.#...##.#.###..##.#.##.##.###..#.###.#.##.....#.#.#...###.##...####.##..
+###.....#.###..###.#.###...#.#.##..#..##.###.#.#####.###.##.#######.#.#.#####.#.#.#.....#......##...
+###.#.#.....#.#.#..#..###.###..#.#....#####.###.##..#.##..#..##.#.##...##.##..##.#....##.#####.....#
+###...######.#.##.#.#..####..##.#.#.#..#.#.##..####..#.#####..#..#..#####.#....#.##.##..##...###.###
+#...###.....#..#..###.....######.#.#.###.#.#####..###.#..#..#..#.#.#..####.#####.#....##.#....##..##
+.##..###..###....#......#.###...##......#.#..##.#..#######.##.########.#...#.###..##.##.#....#...###
+....##..#..##..###..#.#####..####.###.###.####........###.#..#.##..#......#.##.###.##.######.#.##.##
+#.##########...###.##.####.....#####..###.....##.##.#..###.##.##.#..##..##....#.###.##.##.######...#
+##.#..#.#.#...###.####...#..##..##.#.#.#.#....#.#..##.#..##.#.#..#####.#..##.#..###.#.######..###.#.
+.#.#.##.#...####.##..##.##.#..##.##.##..#....###....#..####.#....###.#...#..##....##.#..######.####.
+.#...#..#.####.##.#..#.#...##...###.#...##....#...##...#....#..##.###.####..######..##.###.#.....#..
+#..#...###..#..#####.#....#..####.#.###..###.####...#...#.#..#...###.#.######.#.#..#.###....####..##
+#.##.##.##..##..#.#..##...##.....#####.#.#..#.#.#.#.#.#.####..##....#####.#...###..#.#..#....##...##
+###..#..#.###.##.##.#######.#..##.#..#.#.###..#.#.##..#.##..#..#.#.##.####..#.#####.#.##.#..###.###.
+#.##.........###.##...####..#.#..###.###...#....#....#.#.#....#.##.#.....##...##........######.##...
+##.#.#.###.####...###..#.....##.##...##.##..###..###..###..#.#..#..##.#########.#####..#####.#####.#
+....#..##....#....#....#.###.#.......#..##.#.##..###....#.#####.#.##..#####.#..####.#...##....#.#...
+.##.##...#..###...#.##..#.###.#...#.#..#.#.#..#.#..#.###.#..###..#.#.#####..#########..#####.##.#.#.
+###..##..#.#..###.#.###.#.#..##.#.....###.#...#....#...#.#.#..##..##..##.#..#.#.####..##...#.#..#.#.
+#..#.####.###..#....#########..#..#.#.####..#.#.....#.##......####..####....#.#..#......#...##.###.#
+....##...#...####...#.#.###..####..####..##.###.##.#.##.###.#####.#.#...#......##.#..###..#....###..
+.##.##..##.###........##..#.###..#.#.#..##......#.......#.#.#........#..#.##..####.####....#####..#.
+..##.#.#......#...##..#..###..#..#..#...###.#.####.#.#.##..#.#.#.#.##..#....######.##.#.#...#.##....
+....##..#..#..##.....#.#.#...####....#...##..#.#.#...#..###...#...#.#.....#####..###.##.#........##.
+##.#......#.#..####...###.....#......#.#.###.###..##.#.#....##.##.....#.#.......##..#...#.#..##....#
+#..##.....#####..#.....#.###..#.#..#.#...###.#.####...####.#.##.####..###.#.#..####.#....#.##.#.##..
+.#.#.####.##..#.##.#..###.#.###..####.#.#..#.#.##...##...#...#.###..##..#...#........##.#.##..#..###
+....#...#..###.#....#..##.....##.####...####.##..#.#.#.###...#..####.###..##...###.#.#.##....#......
+##....##.##..#.......##.#...#..#.####...#..##.#.###.#.#....####.####.##.###.##.#..##..#.#.###.#..#.#
+#...#....#.####.##....#...##.##.#..##.#...######...#.#.#..#.#.#..#.#.###.###..#.#.#.#.##.#...#.#....
+......#...##.###..##.#####..#..#..#...##.####.##...#.###...#.##...###.############..##..###.###.##.#
+..#..##.....##..#.##.#.#....#.....##.....#.#..##...##..#.#...#..#..........####..#.####.#.#.....###.
+.#..#..#########.#.#.#.###..###.#.##.#.#...#......######..#.#.###.##.#...#.##.###..#.#.#..#...#.#.#.
+.#..#.#.#.#.#..######.#.....#.####....#..#.#..###.#..##.#.#...#.###...#....###...#.#...#.##...#..##.
+#.##.##.#..#######.##..#...#.###............###.#..##.###.###....####.#..#####...###..#.####....##.#
+...###.#...##..#.#########..#.###.##...#...##.##...#........###..######..##....#.....####.##....###.
+.#..#..##...#######.#.##...#.#......#.##.#..#.#...##..######.#####..#..#..#...#..#........#.##.##..#
+#.#..####.#.#.###...#...#.#.#.#..#.##....###...#.#...##...##.#####.#.#.#.##.##..####.#.##.##.##.....
+####.###..........#.#.##.#..###.#..#....#.##.#.##.###.######......#.##...#..#..#..###..##.########.#
+##...##.#.###..#...#.###......#######......#.#.###..#.##..####.#.####..#.#....#.#.#.##..#..###..#.#.
+#.###.##..##.#.......###...##.##.###.##.####.##..###..##.#.###.#...#...#.#...##..##..#....#.#.#..###
+.###..##...#....##...#...#.###..#.#####.##..####.##..###.##.#...##.##..########..#.#.##..#.#.#.....#
+###.....#...#...#....###..#...#....#.#....#...#...##.#...##.#...##...#...#..#.#.##...#.###....##.##.
+.#.##.###...#..###.##....##..##..#.#.##..#.#..###..#.##...#..##...##..#...#....#..#..####..#...#..#.
+#..#.#.#..##.#.##.#..####.##..#....#.#.#.#.##...#.#.#...#.#.#.#.#.##.##....#####.#.###.###..#.####..
+.#.#....#####..#.#.###.#....#.#.#.##..##.##....##..#..#..#....####..#.###.....#..###.#.##.#.#.##.#.#
+#..#..###..#...###...##.#.#.##....#..#.#.#.###...#....#...##..###.##.#.##..####.######..#.####..####
+##.##.###.###.#.###.#..#.###.....#..##.#..###.####.#.#.##.#..#.#...#....#.###.#####.##.#.#.##....###
+...#.#.###..#..#.#.#..###...#.#..###.#.####..#..##.##..#.##.###...##.##..#.##.####.##..##..##.###..#
+##.#...#..#.##..#####..#....##....####....###.##......#..#..#.##.######.##....#.#.###...#.###.....#.
+###.######.#...##...##.#...##..#.#....#......#..#.#.#.####.#######..#...#...##.#.#.#.#.##.#.#..#..##
+....####...##.#...#.###..#.......#####.#.#.#.##.#.##..#....######.##..#..#..#....#.#.#.#..#..#.##..#
+#..##.#....#.##.##..#.#..#.##.##.#..#.##.#...##..###..###.#.##########.....##.#...##..##.##....#.###
+###.#..#.###.##..#.#.#..#..#..#...##.#.#..#..#..###..#.#.#..###..##.#...##.#.....#.#####..##.#.###.#
+...#.#.#..#.#...##..###...#.##.#.#.#....##..#####.#.##.####..##.##.#.##...###..#####..#...#.#...#...
+..##.###....#...#####.#..#...#.##...####.##...##...#####......#####.....#..#..####.###.###..##..###.
+#####.##.#.#.#.###.##.#.....#..##..#..##.#..#..#..#.##..#..#.#..#...#.###..#..####....#.###..##.#.#.
+#.#.##.#...##.#.####....#....#...#.#..##....#.##....##..#..#.#.##.#.##.#.###..####.#######.#...#.#..
+#####..#.##.....####..#..#.####.##..##.#....#..#..#......#.###..#......#...##.....#..###.#.#...##.#.
+#.#.#######.###....###...#.#...#...###.#...#.######..#.######..###...##....#..##..##.##..#.#.##..#.#
+.##....#..##..###....##.###....####...#..#.#..###...##.#.##...#....#...#.#.###..#....#.###...##....#
+..##..#.....##..##....#..###.##.#...######.#...#.#.#.##...#...#.##.#.....##.###.###..#.###..##..##..
+##...##.#.#..##.#.#.##.###.#.##...#......#.#..#.####.###.#....#...#..###.#.#..#.##.#.####....##.##..
+#.#.....#...#..#####....#.....#.#.#.....##.##.#########.#..#..##..#...#..###...##..#..##.....#.#.#..
+#......#..##..#.###..##.#..#.#.###.#....#...#......##.....###..#..###.........#.##.#.##.##.#...#..#.
+#.#.##....##.#.###.####.##...####....#####.##.#....#.#.#.#.#..#.#...#.....########.##.#.#..#....#.#.
+.#..##.#...##.#.######.#.#.##..####...#..#..##.###..####.##.#.#...##.#...##.###..##...####.#...##...
+.###.#..#.##..#.##.##.#.#..######..#....#.###.#..######.#..#...####.........#.#.##.###.##.#.#.#.###.
+..#...###.####....###.######.##.#...##.#...###..#########....#.#..##..##...#...#..##.##.#########..#
+.#..#...##..#..##.#.#..#.#.......##..##.#.#..#..#.....#...##.#.###..#.#.#...###.#####.##.##.#...##..
+#....#.#.......##.#####......###.##....#...#.......###....#.####..##.##.#.#.#.#..####.#...#....#..#.
+.........#.###.#.#####.#...#.#.#.###....###..#.###...##..#....##.#.###.#.##.#.#.##..#.#.###.#.#.##.#
+.##.######.#..#.###.#...#######.#.##.##....###.#####..###.#...###.#..###.#.#.##.#..#.#.#..#..##..###
+#....#..###..#.....#..####.#.##....####.#.###......###..##.##..#..#.#..#.#.######.#..#.##..##.###..#
+..#.#..#.#.##.#..##.#.#.##.##..#.#.#...#.##.##.#.#.####.###.###..######..#..#..##.#..###..#.##...###
+.......#..####....#..###..####.#..##..#..#.....#.##.##.#..##.#.##...#.###......#.#..#..#.##.#.#.#..#
+..#..#.#..##########...##..#..##.##...#...#..#.##..###..#.#...##.##.#####..#....###...##.#.#..#..##.
+#.###..#..#..#.#.##.#####.#.....#....##.#.#...#.##...####.##....##..###..#.##.##..#...##...##...####
+#####..#..#....####.##..#.#######..#....#########...##....#....#..#.#.##...########..#.#...##..##...
+######.##.##.#.##########.####.#.#.#...##.##..#.#..##..#.##.....#.###...###...#.#.#.##.....###.##..#
+..###....#..##...#.#...##..#..####.#.#.####.#.#......##.#..###.######.#.#....##.##...##.##..#.##.###
+##..####..####.#####....#..##.#.#####.#..###..####.#......##.###....#...#..#....#..#.####.####...###
+..#..###.#.##..#.#...#.##..#.#########..#..###..#..####.#....#.#..###...#.#..#.....#..###.####..###.
+.##...####..#.###..#.#..#.##.#...####...#.#.#.........##..#.....#.##......#####.#.###..#####.###.#..
+###.##.##.#..#..##.####...###.#.#...#######.###.#..###.#.##.#...##..##..#...#...####.#.###....#..#..
+..###...###..#.....#..##.##.#.#..#..#.######.#....#.##..#.#.####...#..##.#....#...###.###.##.#..#.##
+..#....###.#.#.#.#...#...#...##.#...#...###..#.###..##.#.....#.####...#.##.####.#....###.#..#...#.##
+####..#...#.####...#####.#####....###.#.....##..#...##..#.#.####..#######.#.###..###..##.###...#.###
+######.##.######..#.##.#.#..#...######.#.##.....####.###.#..#.#..##....#...##..#.#.##..#....#......#
+.#.##..##.###.#..##.#...####..##...##..#.#.####.##..#.######....#####..##.#.#####...#.#...#.###.....
diff --git a/day20/main.c b/day20/main.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+
+void puzzle(const char *filename, long long *res1, long long *res2);
+
+int main(int argc, char *argv[]) {
+ printf("Advent of Code: day 20\n");
+ double time_start = clock();
+
+ if (argc <= 1) {
+ printf("Usage: %s inputfile.txt\n", argv[0]);
+ return -1;
+ }
+
+ const char *filename = argv[1];
+ long long counter1 = -1;
+ long long counter2 = -1;
+
+ puzzle(filename, &counter1, &counter2);
+
+ printf("Puzzle #1: %lld\n", counter1);
+ printf("Puzzle #2: %lld\n", counter2);
+
+ double elapsed = clock() - time_start;
+ printf("Elapsed: %f\n", elapsed / CLOCKS_PER_SEC);
+
+ return 0;
+}
diff --git a/day20/puzzle.c b/day20/puzzle.c
@@ -0,0 +1,186 @@
+#define _DEFAULT_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+#include <assert.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <math.h>
+
+#include "util.h"
+
+#define STR_LEN 1024
+#define PATTERNS_LEN 512
+#define PATTERN_SIZE 9
+#define PATTERN_WIDTH 3
+
+struct pic_t {
+ char *pic;
+ int w, h;
+ int def;
+};
+
+char * parse_patterns(const char *str);
+void parse_pic(struct pic_t *pic, const char *str);
+void print_pic(struct pic_t *pic);
+struct pic_t * enhance(struct pic_t *pic, const char *patterns);
+int make_pattern(const char pixels[PATTERN_SIZE]);
+int get_pattern(struct pic_t *pic, int x, int y, int def);
+int count_pixels(struct pic_t *pic);
+
+void puzzle(const char *filename, long long *result1, long long *result2) {
+ FILE *infile = fopen(filename, "r");
+ if (infile == NULL) {
+ fprintf(stderr, "fopen() error: %s\n", strerror(errno));
+ return;
+ }
+
+ char buf[STR_LEN] = {0};
+ unsigned int line_num = 0;
+ char *patterns = NULL;
+ struct pic_t *pic = malloc(sizeof(struct pic_t));
+ bzero(pic, sizeof(struct pic_t));
+
+ while (fgets(buf, STR_LEN, infile) != NULL) {
+ if (line_num == 0) {
+ // first line is always patterns
+ patterns = parse_patterns(buf);
+ } else if (line_num > 1) {
+ // initial picture is square
+ assert(buf[0] != '\n');
+ parse_pic(pic, buf);
+ pic->h = line_num-1;
+ }
+ ++line_num;
+ bzero(buf, STR_LEN);
+ }
+
+ assert(pic->w == pic->h);
+
+ for (int i = 0; i < 50; ++i) {
+ pic = enhance(pic, patterns);
+ if (i == 1) {
+ *result1 = count_pixels(pic);
+ }
+ }
+
+ *result2 = count_pixels(pic);
+
+ free(patterns);
+ free(pic);
+ // mutiny! ignoring feof/ferror.
+ fclose(infile);
+}
+
+int count_pixels(struct pic_t *pic) {
+ int cnt = 0;
+ for (int i = 0; i < pic->w * pic->h; ++i) {
+ cnt += pic->pic[i];
+ }
+ return cnt;
+}
+
+int make_pattern(const char pixels[PATTERN_SIZE]) {
+ int p = 0;
+ for (int i = 0; i < PATTERN_SIZE; ++i) {
+ int ind = PATTERN_SIZE-i-1;
+ assert(ind >= 0 && ind < PATTERN_SIZE);
+ p |= (pixels[ind] << i);
+ //printf("bit %d = %d, ind=%d, p=%d\n", i, pixels[ind], ind, p);
+ }
+ return p;
+}
+
+struct pic_t * enhance(struct pic_t *pic, const char *patterns) {
+ assert(patterns != NULL);
+ assert(pic != NULL);
+
+ struct pic_t *pic1 = malloc(sizeof(struct pic_t));
+ assert(pic1 != NULL);
+ bzero(pic1, sizeof(struct pic_t));
+ static const int growth = 1;
+ pic1->w = pic->w + growth*2;
+ pic1->h = pic->h + growth*2;
+ pic1->pic = calloc(pic1->w * pic1->h, sizeof(char));
+ assert(pic1->pic != NULL);
+
+ for (int y1 = 0; y1 < pic1->h; ++y1) {
+ for (int x1 = 0; x1 < pic1->w; ++x1) {
+ int p = get_pattern(pic, x1 - growth, y1 - growth, pic->def);
+ assert(p < PATTERNS_LEN);
+ pic1->pic[y1 * pic1->w + x1] = patterns[p];
+ }
+ }
+ if (patterns[0] == 1 && patterns[511] == 0) {
+ pic1->def = !pic->def;
+ }
+
+ free(pic->pic);
+ free(pic);
+
+ return pic1;
+}
+
+int get_pattern(struct pic_t *pic, int x, int y, int def) {
+ assert(pic != NULL);
+ assert(pic->pic != NULL);
+ char p[PATTERN_SIZE] = {0};
+ memset(&p, def, PATTERN_SIZE);
+
+ for (int dy = -1; dy <= 1; ++dy) {
+ for (int dx = -1; dx <= 1; ++dx) {
+ int index = 3*(dy+1) + (dx+1);
+ int x1 = x+dx;
+ int y1 = y+dy;
+ if (x1 >= 0 && y1 >= 0 && x1 < pic->w && y1 < pic->h) {
+ p[index] = pic->pic[y1 * pic->h + x1];
+ }
+ }
+ }
+ return make_pattern(p);
+}
+
+char * parse_patterns(const char *str) {
+ int len = strlen(str);
+ assert(len-1 == PATTERNS_LEN);
+ char *patterns = calloc(len, sizeof(char));
+ assert(patterns != NULL);
+ for (int i = 0; i < PATTERNS_LEN; ++i) {
+ if (str[i] == '.') patterns[i] = 0;
+ else if (str[i] == '#') patterns[i] = 1;
+ else break;
+ }
+ return patterns;
+}
+
+void parse_pic(struct pic_t *pic, const char *str) {
+ assert(pic != NULL);
+ assert(str != NULL);
+ int len = strlen(str) - 1;
+ assert(len > 0);
+
+ if (pic->pic == NULL) {
+ pic->pic = calloc(len*len, sizeof(char));
+ assert(pic->pic != NULL);
+ pic->w = len;
+ }
+
+ assert(len == pic->w);
+
+ for (int i = 0; i < len; ++i) {
+ if (str[i] == '.') pic->pic[pic->h * len+i] = 0;
+ else if (str[i] == '#') pic->pic[pic->h * len+i] = 1;
+ }
+}
+
+void print_pic(struct pic_t *pic) {
+ for (int y = 0; y < pic->h; ++y) {
+ for (int x = 0; x < pic->w; ++x) {
+ printf("%c", pic->pic[y * pic->h + x] == 1 ? '#' : '.');
+ }
+ printf("\n");
+ }
+}
diff --git a/day20/test.txt b/day20/test.txt
@@ -0,0 +1,7 @@
+..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..###..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###.######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#..#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#......#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#.....####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.......##..####..#...#.#.#...##..#.#..###..#####........#..####......#..#
+
+#..#.
+#....
+##..#
+..#..
+..###