advent2021

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

commit cdaa9ee3e67d079c3806497cfbb6fe68739a794b
parent c264ecb29c6f47ba1fb60a17914a2ba8958c7fd1
Author: bsandro <[email protected]>
Date:   Wed, 22 Dec 2021 01:28:38 +0200

Day 21, puzzle 1 (trashcan solution)

Diffstat:
Aday21/Makefile | 25+++++++++++++++++++++++++
Aday21/input.txt | 2++
Aday21/main.c | 29+++++++++++++++++++++++++++++
Aday21/puzzle.c | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aday21/test.txt | 2++
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