advent2021

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

puzzle.c (2996B)


      1 #define _DEFAULT_SOURCE
      2 
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <errno.h>
      6 #include <string.h>
      7 #include <strings.h>
      8 #include <assert.h>
      9 #include <stdbool.h>
     10 #include <unistd.h>
     11 
     12 #include "util.h"
     13 
     14 #define STR_LEN 1024
     15 
     16 struct vec2_t {
     17 	int x, y;
     18 };
     19 
     20 void array_push(struct array_t *array, int val);
     21 bool probe(struct vec2_t velocity, struct vec2_t (*target)[2], int *max_y);
     22 void add_velocity(struct array_t *array, struct vec2_t *velocity);
     23 int compare(const void *l, const void *r);
     24 
     25 void puzzle(const char *filename, long long *result1, long long *result2) {
     26 	FILE *infile = fopen(filename, "r");
     27 	if (infile == NULL) {
     28 		fprintf(stderr, "fopen() error: %s\n", strerror(errno));
     29 		return;
     30 	}
     31 
     32 	char buf[STR_LEN] = {0};
     33 	unsigned int line_num = 0;
     34 
     35 	*result1 = 0;
     36 	*result2 = 0;
     37 
     38 	//@todo actual parsing
     39 
     40 	while (fgets(buf, STR_LEN, infile) != NULL) {
     41 		++line_num;
     42 		bzero(buf, STR_LEN);
     43 	}
     44 
     45 	struct vec2_t target[2] = {
     46 //		{.x=20, .y=-5},
     47 //		{.x=30, .y=-10}
     48 		{.x=156, .y=-69},
     49 		{.x=202, .y=-110}
     50 	};
     51 
     52 	struct array_t heights = { .data=NULL };
     53 	array_init(&heights, sizeof(int), 100);
     54 
     55 	struct array_t velocities = { .data=NULL };
     56 	array_init(&velocities, sizeof(struct vec2_t), 100);
     57 
     58 	for (int x = 0; x < 1000; ++x) {
     59 		for (int y = target[1].y; y < 1000; ++y) {
     60 			struct vec2_t velocity = {.x=x, .y=y};
     61 			int max_y = 0;
     62 
     63 			if (probe(velocity, &target, &max_y)) {
     64 				array_push(&heights, max_y);
     65 				add_velocity(&velocities, &velocity);
     66 			}
     67 		}
     68 	}
     69 
     70 	if (heights.count > 0) {
     71 		qsort(heights.data, heights.count, heights.elem_size, compare);
     72 		int *data = heights.data;
     73 		*result1 = data[0];
     74 	}
     75 
     76 	*result2 = velocities.count;
     77 
     78 	//PRINT_ARRAY(heights, int)
     79 	// mutiny! ignoring feof/ferror.
     80 	fclose(infile);
     81 }
     82 
     83 bool probe(struct vec2_t velocity, struct vec2_t (*target)[2], int *max_y) {
     84 	struct vec2_t pos = {0};
     85 	*max_y = 0;
     86 	while (pos.y > (*target)[1].y) { //&& pos.y < (*target)[1].y) {
     87 		pos.x += velocity.x;
     88 		pos.y += velocity.y;
     89 		if (velocity.x > 0) {
     90 			velocity.x -= 1;
     91 		} else if (velocity.x < 0) {
     92 			velocity.x += 1;
     93 		}
     94 		velocity.y -= 1;
     95 		//printf("vx:%d, vy:%d x:%d, y:%d\n", velocity.x, velocity.y, pos.x, pos.y);
     96 		*max_y = pos.y > *max_y ? pos.y : *max_y;
     97 
     98 		if (pos.x >= (*target)[0].x && pos.x <= (*target)[1].x &&
     99 			pos.y <= (*target)[0].y && pos.y >= (*target)[1].y) {
    100 			return true;
    101 		}
    102 	}
    103 
    104 	return false;
    105 }
    106 
    107 void array_push(struct array_t *array, int val) {
    108 	if (array->count >= array->cap) {
    109 		array_expand(array);
    110 	}
    111 	int *data = array->data;
    112 	data[array->count++] = val;
    113 }
    114 
    115 void add_velocity(struct array_t *array, struct vec2_t *velocity) {
    116 	for (size_t i = 0; i < array->count; ++i) {
    117 		struct vec2_t *data = array->data;
    118 		if (data[i].x == velocity->x && data[i].y == velocity->y) {
    119 			return; // only distinct values
    120 		}
    121 	}
    122 
    123 	if (array->count >= array->cap) {
    124 		array_expand(array);
    125 	}
    126 	struct vec2_t *data = array->data;
    127 	data[array->count++] = *velocity;
    128 }
    129 
    130 int compare(const void *l, const void *r) {
    131 	return *(int *)r - *(int *)l;
    132 }