commit cdaa9ee3e67d079c3806497cfbb6fe68739a794b
parent c264ecb29c6f47ba1fb60a17914a2ba8958c7fd1
Author: bsandro <[email protected]>
Date: Wed, 22 Dec 2021 01:28:38 +0200
Day 21, puzzle 1 (trashcan solution)
Diffstat:
5 files changed, 182 insertions(+), 0 deletions(-)
diff --git a/day21/Makefile b/day21/Makefile
@@ -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 -lm -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/day21/input.txt b/day21/input.txt
@@ -0,0 +1,2 @@
+Player 1 starting position: 8
+Player 2 starting position: 3
diff --git a/day21/main.c b/day21/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 21\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/day21/puzzle.c b/day21/puzzle.c
@@ -0,0 +1,124 @@
+#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
+
+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;
+
+ long p1 = 0;
+ long p2 = 0;
+
+ while (fgets(buf, STR_LEN, infile) != NULL) {
+ int len = strlen(buf);
+ assert(len > 2);
+ if (line_num == 0) { // player 1
+ p1 = buf[len-2] - '0';
+ } else if (line_num == 1) { // player 2
+ p2 = buf[len-2] - '0';
+ }
+ ++line_num;
+ bzero(buf, STR_LEN);
+ }
+
+ assert(p1 != 0 && p2 != 0);
+
+ *result2 = 0;
+ long p1s = 0; // player 1 score
+ long p2s = 0; // player 2 score
+ long d = 1; // dice value
+ long rc = 0; // real rolls count
+
+ while (1) {
+ //printf("rc=%3ld, d=%3ld, ", rc, d);
+ if (d == 1) {
+ p1 += 6;
+ d += 3;
+ } else if (d >= 98) {
+ if (d == 98) {
+ p1 += 297;
+ d = 1;
+ } else if (d == 99) {
+ p1 += 200;
+ d = 2; //(d + 3) % 100;
+ } else if (d == 100) {
+ p1 += 103;
+ d = 3; //(d + 3) % 100;
+ } else {
+ d = (d + 3) % 100;
+ p1 += d * 3 + 3;
+ }
+ } else {
+ p1 += d * 3 + 3;
+ d += 3;
+ }
+ //printf("p1=%3ld, ", p1);
+ p1 = p1 > 10 ? (p1 % 10) : p1;
+ p1 = p1 == 0 ? 10 : p1;
+ //printf("p1(pos)=%3ld, ", p1);
+ p1s += p1;
+ //printf("p1s=%3ld\n", p1s);
+ rc += 3;
+
+ if (p1s >= 1000) break;
+
+ //printf("rc=%3ld, d=%3ld, ", rc, d);
+ if (d == 1) {
+ p2 += 6;
+ d += 3;
+ } else if (d >= 98) {
+ if (d == 98) {
+ p2 += 297;
+ d = 1;
+ } else if (d == 99) {
+ p2 += 200;
+ d = 2; //(d + 3) % 100;
+ } else if (d == 100) {
+ p2 += 103;
+ d = 3; //(d + 3) % 100;
+ } else {
+ d = (d + 3) % 100;
+ p2 += d * 3 + 3;
+ }
+ } else {
+ p2 += d * 3 + 3;
+ d += 3;
+ }
+ //printf("p2=%3ld, ", p2);
+ p2 = p2 > 10 ? (p2 % 10) : p2;
+ p2 = p2 == 0 ? 10 : p2;
+ //printf("p2(pos)=%3ld, ", p2);
+ p2s += p2;
+ //printf("p2s=%3ld\n\n", p2s);
+ rc += 3;
+
+ if (p2s >= 1000) break;
+ }
+
+ //printf("\n\n\np1=%3ld, p1s=%3ld, p2=%3ld, p2s=%3ld, rc=%3ld\n", p1, p1s, p2, p2s, rc);
+
+ long min_score = fmin(p1s, p2s);
+
+ *result1 = min_score * rc;
+
+ // mutiny! ignoring feof/ferror.
+ fclose(infile);
+}
diff --git a/day21/test.txt b/day21/test.txt
@@ -0,0 +1,2 @@
+Player 1 starting position: 4
+Player 2 starting position: 8