advent2021

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

commit 6a74421ce22aa41c12ba46eec2db98ae26163fcf
parent 0870cb87f14280ff5bc804ce8b7f4be494278fce
Author: bsandro <[email protected]>
Date:   Sat, 18 Dec 2021 09:00:54 +0200

Day 17, puzzles 1-2 (hacky lazy variant that I am ashamed of)

Diffstat:
Aday17/Makefile | 25+++++++++++++++++++++++++
Aday17/input.txt | 1+
Aday17/main.c | 29+++++++++++++++++++++++++++++
Aday17/puzzle.c | 132+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aday17/test.txt | 1+
5 files changed, 188 insertions(+), 0 deletions(-)

diff --git a/day17/Makefile b/day17/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/day17/input.txt b/day17/input.txt @@ -0,0 +1 @@ +target area: x=156..202, y=-110..-69 diff --git a/day17/main.c b/day17/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 17\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/day17/puzzle.c b/day17/puzzle.c @@ -0,0 +1,132 @@ +#define _DEFAULT_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <strings.h> +#include <assert.h> +#include <stdbool.h> +#include <unistd.h> + +#include "util.h" + +#define STR_LEN 1024 + +struct vec2_t { + int x, y; +}; + +void array_push(struct array_t *array, int val); +bool probe(struct vec2_t velocity, struct vec2_t (*target)[2], int *max_y); +void add_velocity(struct array_t *array, struct vec2_t *velocity); +int compare(const void *l, const void *r); + +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; + + *result1 = 0; + *result2 = 0; + + //@todo actual parsing + + while (fgets(buf, STR_LEN, infile) != NULL) { + ++line_num; + bzero(buf, STR_LEN); + } + + struct vec2_t target[2] = { +// {.x=20, .y=-5}, +// {.x=30, .y=-10} + {.x=156, .y=-69}, + {.x=202, .y=-110} + }; + + struct array_t heights = { .data=NULL }; + array_init(&heights, sizeof(int), 100); + + struct array_t velocities = { .data=NULL }; + array_init(&velocities, sizeof(struct vec2_t), 100); + + for (int x = 0; x < 1000; ++x) { + for (int y = target[1].y; y < 1000; ++y) { + struct vec2_t velocity = {.x=x, .y=y}; + int max_y = 0; + + if (probe(velocity, &target, &max_y)) { + array_push(&heights, max_y); + add_velocity(&velocities, &velocity); + } + } + } + + if (heights.count > 0) { + qsort(heights.data, heights.count, heights.elem_size, compare); + int *data = heights.data; + *result1 = data[0]; + } + + *result2 = velocities.count; + + //PRINT_ARRAY(heights, int) + // mutiny! ignoring feof/ferror. + fclose(infile); +} + +bool probe(struct vec2_t velocity, struct vec2_t (*target)[2], int *max_y) { + struct vec2_t pos = {0}; + *max_y = 0; + while (pos.y > (*target)[1].y) { //&& pos.y < (*target)[1].y) { + pos.x += velocity.x; + pos.y += velocity.y; + if (velocity.x > 0) { + velocity.x -= 1; + } else if (velocity.x < 0) { + velocity.x += 1; + } + velocity.y -= 1; + //printf("vx:%d, vy:%d x:%d, y:%d\n", velocity.x, velocity.y, pos.x, pos.y); + *max_y = pos.y > *max_y ? pos.y : *max_y; + + if (pos.x >= (*target)[0].x && pos.x <= (*target)[1].x && + pos.y <= (*target)[0].y && pos.y >= (*target)[1].y) { + return true; + } + } + + return false; +} + +void array_push(struct array_t *array, int val) { + if (array->count >= array->cap) { + array_expand(array); + } + int *data = array->data; + data[array->count++] = val; +} + +void add_velocity(struct array_t *array, struct vec2_t *velocity) { + for (size_t i = 0; i < array->count; ++i) { + struct vec2_t *data = array->data; + if (data[i].x == velocity->x && data[i].y == velocity->y) { + return; // only distinct values + } + } + + if (array->count >= array->cap) { + array_expand(array); + } + struct vec2_t *data = array->data; + data[array->count++] = *velocity; +} + +int compare(const void *l, const void *r) { + return *(int *)r - *(int *)l; +} diff --git a/day17/test.txt b/day17/test.txt @@ -0,0 +1 @@ +target area: x=20..30, y=-10..-5