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:
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