Skip to content

Commit

Permalink
Day 18, Part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeladler committed Dec 21, 2023
1 parent 074379f commit 68d863c
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 52 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ Compiled using clang 16 and LTO.
| 15 | 1.1 ms | 1 ms |
| 16 | 34.4 ms | 33.5 ms |
| 17 | 315.3 ms | 604 ms |
| 18 | | 379 us |

## 🙏 Acknowledgments and Resources

Expand Down
40 changes: 16 additions & 24 deletions puzzle/day18.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@

--- Day 18: Lavaduct Lagoon ---

Thanks to your efforts, the machine parts factory is one of the first factories up and running since the lavafall came back. However, to
catch up with the large backlog of parts requests, the factory will also need a large supply of lava for a while; the Elves have already
Thanks to your efforts, the machine parts factory is one of the first factories up and running since the lavafall came back. However, to catch up with the large backlog of parts requests, the factory will also need a large supply of lava for a while; the Elves have already
started creating a large lagoon nearby for this purpose.

However, they aren't sure the lagoon will be big enough; they've asked you to take a look at the dig plan (your puzzle input). For
example:
However, they aren't sure the lagoon will be big enough; they've asked you to take a look at the dig plan (your puzzle input). For example:

R 6 (#70c710)
D 5 (#0dc571)
Expand All @@ -23,13 +21,10 @@ U 3 (#a77fa3)
L 2 (#015232)
U 2 (#7a21e3)

The digger starts in a 1 meter cube hole in the ground. They then dig the specified number of meters up (U), down (D), left (L), or
right (R), clearing full 1 meter cubes as they go. The directions are given as seen from above, so if "up" were north, then "right"
would be east, and so on. Each trench is also listed with the color that the edge of the trench should be painted as an RGB hexadecimal
color code.
The digger starts in a 1 meter cube hole in the ground. They then dig the specified number of meters up (U), down (D), left (L), or right (R), clearing full 1 meter cubes as they go. The directions are given as seen from above, so if "up" were north, then "right" would be
east, and so on. Each trench is also listed with the color that the edge of the trench should be painted as an RGB hexadecimal color code.

When viewed from above, the above example dig plan would result in the following loop of trench (#) having been dug out from otherwise
ground-level terrain (.):
When viewed from above, the above example dig plan would result in the following loop of trench (#) having been dug out from otherwise ground-level terrain (.):

#######
#.....#
Expand All @@ -42,8 +37,7 @@ ground-level terrain (.):
.#....#
.######

At this point, the trench could contain 38 cubic meters of lava. However, this is just the edge of the lagoon; the next step is to dig
out the interior so that it is one meter deep as well:
At this point, the trench could contain 38 cubic meters of lava. However, this is just the edge of the lagoon; the next step is to dig out the interior so that it is one meter deep as well:

#######
#######
Expand All @@ -56,24 +50,19 @@ out the interior so that it is one meter deep as well:
.######
.######

Now, the lagoon can contain a much more respectable 62 cubic meters of lava. While the interior is dug out, the edges are also painted
according to the color codes in the dig plan.
Now, the lagoon can contain a much more respectable 62 cubic meters of lava. While the interior is dug out, the edges are also painted according to the color codes in the dig plan.

The Elves are concerned the lagoon won't be large enough; if they follow their dig plan, how many cubic meters of lava could it hold?

Your puzzle answer was 52231.

The first half of this puzzle is complete! It provides one gold star: *

--- Part Two ---

The Elves were right to be concerned; the planned lagoon would be much too small.

After a few minutes, someone realizes what happened; someone swapped the color and instruction parameters when producing the dig plan.
They don't have time to fix the bug; one of them asks if you can extract the correct instructions from the hexadecimal codes.
After a few minutes, someone realizes what happened; someone swapped the color and instruction parameters when producing the dig plan. They don't have time to fix the bug; one of them asks if you can extract the correct instructions from the hexadecimal codes.

Each hexadecimal code is six hexadecimal digits long. The first five hexadecimal digits encode the distance in meters as a five-digit
hexadecimal number. The last hexadecimal digit encodes the direction to dig: 0 means R, 1 means D, 2 means L, and 3 means U.
Each hexadecimal code is six hexadecimal digits long. The first five hexadecimal digits encode the distance in meters as a five-digit hexadecimal number. The last hexadecimal digit encodes the direction to dig: 0 means R, 1 means D, 2 means L, and 3 means U.

So, in the above example, the hexadecimal codes can be converted into the true instructions:

Expand All @@ -94,12 +83,15 @@ So, in the above example, the hexadecimal codes can be converted into the true i

Digging out this loop and its interior produces a lagoon that can hold an impressive 952408144115 cubic meters of lava.

Convert the hexadecimal color codes into the correct instructions; if the Elves follow this new dig plan, how many cubic meters of lava
could the lagoon hold?
Convert the hexadecimal color codes into the correct instructions; if the Elves follow this new dig plan, how many cubic meters of lava could the lagoon hold?

Your puzzle answer was 57196493937398.

Both parts of this puzzle are complete! They provide two gold stars: **

Answer:
At this point, you should return to your Advent calendar and try another puzzle.

Although it hasn't changed, you can still get your puzzle input.
If you still want to see it, you can get your puzzle input.

You can also [Shareon Twitter Mastodon] this puzzle.

76 changes: 50 additions & 26 deletions src/day18/solve.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,45 +9,69 @@
#include "solve.h"
#include "aoc/all.h"

void solve(char *buf, size_t buf_size, Solution *result) {
int part1 = 0, part2 = 0;
static inline int hex_to_int(char c) {
if (c >= '0' && c <= '9') { return c - '0'; }
return c - 'a' + 10;
}

typedef struct {
i64 x, y;
i64 area;
i64 boundary;
} data_t;

static inline void update_data(data_t *data, char direction, i64 steps) {
int x_new = data->x, y_new = data->y;
switch (direction) {
case 'U': y_new -= steps; break;
case 'D': y_new += steps; break;
case 'R': x_new += steps; break;
case 'L': x_new -= steps; break;
}
// Shoelace formula (https://en.wikipedia.org/wiki/Shoelace_formula)
data->area += (data->x * y_new - x_new * data->y);
data->boundary += steps;
data->x = x_new;
data->y = y_new;
}

static inline i64 calc_area(data_t *data) {
// Pick's theorem (https://en.wikipedia.org/wiki/Pick%27s_theorem)
return (data->area + data->boundary) / 2 + 1;
}

int y = 0, x = 0;
int area = 0, boundary = 1;
void solve(char *buf, size_t buf_size, Solution *result) {
data_t p1 = {.boundary = 1}, p2 = {.boundary = 1};
for (size_t pos = 0; pos < buf_size;) {
char d = buf[pos++];
char p1_direction = buf[pos++];
pos++;
int steps = aoc_parse_nonnegative(buf, &pos);
int p1_steps = aoc_parse_nonnegative(buf, &pos);

aoc_parse_seek(buf, &pos, '#');
pos++;
char color[6];
for (int i = 0; i < 6; i++) { color[i] = buf[pos++]; }

aoc_parse_seek(buf, &pos, '\n');
pos++;

// part 1
int x_new = x, y_new = y;
switch (d) {
case 'U': y_new -= steps; break;
case 'D': y_new += steps; break;
case 'R': x_new += steps; break;
case 'L': x_new -= steps; break;
i64 p2_steps = 0;
for (int i = 0; i < 5; i++) { p2_steps = 16 * p2_steps + hex_to_int(buf[pos++]); }
char p2_direction;
switch (buf[pos++]) {
case '0': p2_direction = 'R'; break;
case '1': p2_direction = 'D'; break;
case '2': p2_direction = 'L'; break;
case '3': p2_direction = 'U'; break;
}

// Shoelace formula (https://en.wikipedia.org/wiki/Shoelace_formula)
area += (x * y_new - x_new * y);
boundary += steps;
aoc_parse_seek(buf, &pos, '\n');
pos++;

x = x_new, y = y_new;
update_data(&p1, p1_direction, p1_steps);
update_data(&p2, p2_direction, p2_steps);
}

// Pick's theorem (https://en.wikipedia.org/wiki/Pick%27s_theorem)
part1 = (area + boundary) / 2 + 1;
i64 part1 = calc_area(&p1);
i64 part2 = calc_area(&p2);

aoc_itoa(part1, result->part1, 10);
aoc_itoa(part2, result->part2, 10);
snprintf(result->part1, sizeof(result->part1), "%ld", part1);
snprintf(result->part2, sizeof(result->part2), "%ld", part2);
}

int solve_input(const char *fname, Solution *result) {
Expand Down
4 changes: 2 additions & 2 deletions src/day18/solve_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ U 2 (#7a21e3)\n";
Solution solution;
solve(buf, strlen(buf), &solution);
ASSERT_STR("62", solution.part1);
ASSERT_STR("0", solution.part2);
ASSERT_STR("952408144115", solution.part2);
}

#ifdef HAVE_INPUTS
CTEST(day18, real) {
Solution solution;
solve_input("input/" DAY ".txt", &solution);
ASSERT_STR("52231", solution.part1);
ASSERT_STR("0", solution.part2);
ASSERT_STR("57196493937398", solution.part2);
}
#endif

Expand Down

0 comments on commit 68d863c

Please sign in to comment.