advent2021

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

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:
Aday24/Makefile | 27+++++++++++++++++++++++++++
Aday24/input.txt | 252+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aday24/main.c | 29+++++++++++++++++++++++++++++
Aday24/puzzle.c | 209+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aday24/test.txt | 11+++++++++++
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, &registers, &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