commit a759041c799d1e2d968b863ca7291a26e7e469b5
parent 3167ff8ee94cbaae373f1febb9cac0aad2759ed3
Author: bsandro <[email protected]>
Date: Fri, 24 Dec 2021 20:40:37 +0200
Day 24, trying to bruteforce p.1 (fruitlessly)
Diffstat:
5 files changed, 528 insertions(+), 0 deletions(-)
diff --git a/day24/Makefile b/day24/Makefile
@@ -0,0 +1,27 @@
+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 -lm -fsanitize=address
+#CFLAGS=-O0 -g -std=c99 -Werror -Wall -Wextra -I. -I../common
+#LDFLAGS=-lc -lm
+
+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/day24/input.txt b/day24/input.txt
@@ -0,0 +1,252 @@
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 13
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 6
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 11
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 11
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 12
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 5
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 10
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 6
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 14
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 8
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -1
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 14
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 14
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 9
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -16
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 4
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -8
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 7
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 12
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 13
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -16
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 11
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -13
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 11
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -6
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 6
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -6
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 1
+mul y x
+add z y
diff --git a/day24/main.c b/day24/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 24\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/day24/puzzle.c b/day24/puzzle.c
@@ -0,0 +1,209 @@
+#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 <unistd.h>
+
+#include "util.h"
+
+#define STR_LEN 1024
+
+struct cmd_t {
+ enum ins_t {INP, ADD, MUL, DIV, MOD, EQL} instruction;
+ int reg1;
+ int reg2;
+ int op2;
+};
+
+struct input_t {
+ int digits[14];
+ int current;
+};
+
+void parse_command(struct array_t *commands, char *str);
+int get_register(char name);
+int exec_cmd(struct cmd_t *cmd, int (*registers)[5], struct input_t *input);
+
+int exec_inp(struct cmd_t *cmd, int (*registers)[5], struct input_t *input);
+int exec_add(struct cmd_t *cmd, int (*registers)[5]);
+int exec_mul(struct cmd_t *cmd, int (*registers)[5]);
+int exec_div(struct cmd_t *cmd, int (*registers)[5]);
+int exec_mod(struct cmd_t *cmd, int (*registers)[5]);
+int exec_eql(struct cmd_t *cmd, int (*registers)[5]);
+
+int read_input(struct input_t *input);
+struct input_t make_input(uint64_t number);
+bool valid_input(struct input_t *input);
+
+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};
+ struct array_t commands = { .data = NULL };
+ array_init(&commands, sizeof(struct cmd_t), 10);
+
+ while (fgets(buf, STR_LEN, infile) != NULL) {
+ parse_command(&commands, buf);
+ bzero(buf, STR_LEN);
+ }
+
+ for (uint64_t i = 99999999999999; i >= 11111111111111; --i) {
+ struct input_t input = make_input(i);
+ if (valid_input(&input)) {
+ int registers[5] = {0};
+ for (size_t k = 0; k < commands.count; ++k) {
+ struct cmd_t *cmd = &((struct cmd_t *)commands.data)[k];
+ exec_cmd(cmd, ®isters, &input);
+ }
+ input.current = 0;
+ if (registers[4] == 0) {
+ *result1 = i;
+ break;
+ }
+ }
+ }
+
+ *result2 = 0;
+
+ // mutiny! ignoring feof/ferror.
+ fclose(infile);
+}
+
+void parse_command(struct array_t *commands, char *str) {
+ assert(commands != NULL);
+ assert(str != NULL);
+ int len = strlen(str);
+ assert(len >= 5);
+ if (commands->count >= commands->cap) array_expand(commands);
+
+ struct cmd_t *cmd = &((struct cmd_t *)commands->data)[commands->count++];
+ if (strncmp(str, "inp", 3) == 0) {
+ cmd->instruction = INP;
+ } else if (strncmp(str, "add", 3) == 0) {
+ cmd->instruction = ADD;
+ } else if (strncmp(str, "mul", 3) == 0) {
+ cmd->instruction = MUL;
+ } else if (strncmp(str, "div", 3) == 0) {
+ cmd->instruction = DIV;
+ } else if (strncmp(str, "mod", 3) == 0) {
+ cmd->instruction = MOD;
+ } else if (strncmp(str, "eql", 3) == 0) {
+ cmd->instruction = EQL;
+ } else {
+ printf("invalid instruction %s", str);
+ exit(1);
+ }
+
+ cmd->reg1 = get_register(str[4]);
+ assert(cmd->reg1 != 0);
+
+ if (len < 7) {
+ return;
+ }
+
+ if (str[6] >= 'a' && str[6] <= 'z') {
+ cmd->reg2 = get_register(str[6]);
+ } else {
+ cmd->op2 = atoi(str+6);
+ }
+}
+
+int get_register(char name) {
+ switch (name) {
+ case 'w': return 1;
+ case 'x': return 2;
+ case 'y': return 3;
+ case 'z': return 4;
+ default: return 0;
+ }
+}
+
+int read_input(struct input_t *input) {
+ return input->digits[input->current++];
+}
+
+struct input_t make_input(uint64_t num) {
+ struct input_t input = {0};
+ for (int i = 0; i < 14; ++i) {
+ uint64_t mod = num % 10;
+ num /= 10;
+ input.digits[13-i] = mod;
+ }
+ return input;
+}
+
+bool valid_input(struct input_t *input) {
+ for (int i = 0; i < 14; ++i) {
+ if (input->digits[i] == 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+int exec_cmd(struct cmd_t *cmd, int (*registers)[5], struct input_t *input) {
+ assert(cmd != NULL);
+ assert(registers != NULL);
+
+ switch (cmd->instruction) {
+ case INP: return exec_inp(cmd, registers, input);
+ case ADD: return exec_add(cmd, registers);
+ case MUL: return exec_mul(cmd, registers);
+ case DIV: return exec_div(cmd, registers);
+ case MOD: return exec_mod(cmd, registers);
+ case EQL: return exec_eql(cmd, registers);
+ }
+}
+
+int exec_inp(struct cmd_t *cmd, int (*registers)[5], struct input_t *input) {
+ assert(cmd != NULL);
+ (*registers)[cmd->reg1] = read_input(input);
+ return (*registers)[cmd->reg1];
+}
+
+int exec_add(struct cmd_t *cmd, int (*registers)[5]) {
+ assert(cmd != NULL);
+ int r = cmd->reg2 > 0 ? (*registers)[cmd->reg2] : cmd->op2;
+ (*registers)[cmd->reg1] += r;
+ return (*registers)[cmd->reg1];
+}
+
+int exec_mul(struct cmd_t *cmd, int (*registers)[5]) {
+ assert(cmd != NULL);
+ int r = cmd->reg2 > 0 ? (*registers)[cmd->reg2] : cmd->op2;
+ (*registers)[cmd->reg1] *= r;
+ return (*registers)[cmd->reg1];
+}
+
+int exec_div(struct cmd_t *cmd, int (*registers)[5]) {
+ assert(cmd != NULL);
+ int r = cmd->reg2 > 0 ? (*registers)[cmd->reg2] : cmd->op2;
+ (*registers)[cmd->reg1] /= r;
+ return (*registers)[cmd->reg1];
+}
+
+int exec_mod(struct cmd_t *cmd, int (*registers)[5]) {
+ assert(cmd != NULL);
+ int r = cmd->reg2 > 0 ? (*registers)[cmd->reg2] : cmd->op2;
+ (*registers)[cmd->reg1] %= r;
+ return (*registers)[cmd->reg1];
+
+}
+
+int exec_eql(struct cmd_t *cmd, int (*registers)[5]) {
+ assert(cmd != NULL);
+ int r = cmd->reg2 > 0 ? (*registers)[cmd->reg2] : cmd->op2;
+ (*registers)[cmd->reg1] = (*registers)[cmd->reg1] == r ? 1 : 0;
+ return (*registers)[cmd->reg1];
+}
diff --git a/day24/test.txt b/day24/test.txt
@@ -0,0 +1,11 @@
+inp w
+add z w
+mod z 2
+div w 2
+add y w
+mod y 2
+div w 2
+add x w
+mod x 2
+div w 2
+mod w 2