advent2021

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

commit 6aef118d598a26b339a578dd83e6dbb09366bacd
parent 99aed221f29a7174d0cddebc9003dbc6779b3d0d
Author: bsandro <[email protected]>
Date:   Sun,  5 Dec 2021 16:12:14 +0200

Day 05, puzzle 2

Diffstat:
Mday05/puzzle.c | 105++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 77 insertions(+), 28 deletions(-)

diff --git a/day05/puzzle.c b/day05/puzzle.c @@ -15,7 +15,8 @@ #define MAP_SIZE 1000 // being tad lazy here - assume that the map sides are no larger than MAP_SIZE -static short map[MAP_SIZE][MAP_SIZE]; +static short map1[MAP_SIZE][MAP_SIZE]; +static short map2[MAP_SIZE][MAP_SIZE]; struct vec2_t { int x; @@ -32,8 +33,10 @@ struct vec2_pair_t make_pair(const char *str); struct vec2_t make_vec2(const char *str); void swap_vec2(struct vec2_t *a, struct vec2_t *b); // swap a and b void print_pair(const struct vec2_pair_t *pair); +bool is_pair_diagonal(const struct vec2_pair_t *pair); void normalize_pair(struct vec2_pair_t *pair); // ensure begin is always smaller number -int mark_map(const struct vec2_pair_t *pair); +int mark_map1(const struct vec2_pair_t *pair); +int mark_map2(const struct vec2_pair_t *pair); void print_map(); /* ****************************************************************** */ @@ -47,15 +50,17 @@ void puzzle(const char *filename, int *result1, int *result2) { char buf[STR_LEN] = {0}; unsigned int line_num = 0; - int danger_points = 0; + + *result1 = 0; + *result2 = 0; while (fgets(buf, STR_LEN, infile) != NULL) { struct vec2_pair_t pair = make_pair(buf); - // only straight lines - if (pair.a.x == pair.b.x || pair.a.y == pair.b.y) { + // only straight and 45deg diagonal lines + if (pair.a.x == pair.b.x || pair.a.y == pair.b.y || is_pair_diagonal(&pair)) { normalize_pair(&pair); - //print_pair(&pair); - danger_points += mark_map(&pair); + *result1 += mark_map1(&pair); + *result2 += mark_map2(&pair); } ++line_num; @@ -64,9 +69,6 @@ void puzzle(const char *filename, int *result1, int *result2) { //print_map(); - *result1 = danger_points; - *result2 = 0; - // mutiny! ignoring feof/ferror. fclose(infile); } @@ -125,10 +127,10 @@ void print_map() { printf("\n--------MAP-----------\n"); for (int y = 0; y < MAP_SIZE; ++y) { for (int x = 0; x < MAP_SIZE; ++x) { - if (map[x][y] == 0) { + if (map2[x][y] == 0) { printf("."); } else { - printf("%d", map[x][y]); + printf("%d", map2[x][y]); } } printf("\n"); @@ -136,36 +138,83 @@ void print_map() { printf("\n-----------------------\n"); } +bool is_pair_diagonal(const struct vec2_pair_t *pair) { + return abs(pair->a.x - pair->b.x) == abs(pair->a.y - pair->b.y); +} + void normalize_pair(struct vec2_pair_t *pair) { - if (pair->a.x == pair->b.x) { - if (pair->a.y > pair->b.y) { - swap_vec2(&pair->a, &pair->b); + if (pair->a.x == pair->b.x && pair->a.y > pair->b.y) { + // straight verticals + swap_vec2(&pair->a, &pair->b); + } else if (pair->a.y == pair->b.y && pair->a.x > pair->b.x) { + // straight horizontals + swap_vec2(&pair->a, &pair->b); + } else if (is_pair_diagonal(pair) && pair->a.x > pair->b.x) { + // normalize diagonals only by x axis + swap_vec2(&pair->a, &pair->b); + } +} + +int mark_map1(const struct vec2_pair_t *pair) { + int count = 0; + + if (pair->a.x == pair->b.x) { // vertical lines + int x = pair->a.x; + for (int y = pair->a.y; y <= pair->b.y; ++y) { + if (++map1[x][y] == 2) { + ++count; + } } - } else if (pair->a.y == pair->b.y) { - if (pair->a.x > pair->b.x) { - swap_vec2(&pair->a, &pair->b); + } else if (pair->a.y == pair->b.y) { // horizontal lines + int y = pair->a.y; + for (int x = pair->a.x; x <= pair->b.x; ++x) { + if (++map1[x][y] == 2) { + ++count; + } } } + + return count; } -int mark_map(const struct vec2_pair_t *pair) { - int sum = 0; - // @todo tidy up? - if (pair->a.x == pair->b.x) { +int mark_map2(const struct vec2_pair_t *pair) { + int count = 0; + + if (pair->a.x == pair->b.x) { // vertical lines int x = pair->a.x; for (int y = pair->a.y; y <= pair->b.y; ++y) { - if (++map[x][y] == 2) { // only counting each overlap once - ++sum; + if (++map2[x][y] == 2) { + ++count; } } - } else if (pair->a.y == pair->b.y) { + } else if (pair->a.y == pair->b.y) { // horizontal lines int y = pair->a.y; for (int x = pair->a.x; x <= pair->b.x; ++x) { - if (++map[x][y] == 2) { - ++sum; + if (++map2[x][y] == 2) { + ++count; + } + } + } else if (is_pair_diagonal(pair)) { // diagonal lines + int x = pair->a.x; + int y = pair->a.y; + if (pair->a.y < pair->b.y) { + for (; x <= pair->b.x && y <= pair->b.y;) { + if (++map2[x][y] == 2) { + ++count; + } + ++x; + ++y; + } + } else { + for (; x <= pair->b.x && y >= pair->b.y;) { + if (++map2[x][y] == 2) { + ++count; + } + ++x; + --y; } } } - return sum; + return count; }