111 lines
2.6 KiB
C
111 lines
2.6 KiB
C
#include <stdint.h>
|
|
|
|
#include "parse.h"
|
|
#include "cartesian.h"
|
|
#include "printf.h"
|
|
#include "memory.h"
|
|
#include "array.h"
|
|
|
|
struct offset {
|
|
int x;
|
|
int y;
|
|
};
|
|
|
|
int walk_trailhead(const char * input,
|
|
int depth,
|
|
int stride,
|
|
int width, int height,
|
|
int x, int y,
|
|
char * reachable)
|
|
{
|
|
if (depth == 9) {
|
|
reachable[y * width + x] = 1;
|
|
return 1;
|
|
}
|
|
|
|
const static struct offset offset[] = {
|
|
{ 1, 0},
|
|
{-1, 0},
|
|
{ 0, 1},
|
|
{ 0, -1},
|
|
};
|
|
|
|
int rating = 0;
|
|
for (int i = 0; i < (sizeof (offset)) / (sizeof (offset[0])); i++) {
|
|
int new_x = x + offset[i].x;
|
|
int new_y = y + offset[i].y;
|
|
if (cartesian_inside(width, height, new_x, new_y)) {
|
|
char c = input[new_y * stride + new_x];
|
|
int new_depth = parse_base10_digit(c);
|
|
if (new_depth == depth + 1) {
|
|
rating += walk_trailhead(input,
|
|
new_depth,
|
|
stride,
|
|
width, height,
|
|
new_x, new_y,
|
|
reachable);
|
|
}
|
|
}
|
|
}
|
|
|
|
return rating;
|
|
}
|
|
|
|
struct rating_score {
|
|
int rating;
|
|
int score;
|
|
};
|
|
|
|
struct rating_score find_trailheads(const char * input, int length,
|
|
int stride,
|
|
int width, int height
|
|
)
|
|
{
|
|
int x = 0;
|
|
int y = 0;
|
|
|
|
char reachable[width * height];
|
|
int total_score = 0;
|
|
int total_rating = 0;
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
if (input[i] == '0') {
|
|
memory_set_char(reachable, 0, width * height);
|
|
int rating = walk_trailhead(input, 0, stride, width, height, x, y, reachable);
|
|
total_rating += rating;
|
|
int score = array_sum_char(reachable, width * height);
|
|
total_score += score;
|
|
}
|
|
if (input[i] == '\n') {
|
|
x = 0;
|
|
y += 1;
|
|
} else {
|
|
x += 1;
|
|
}
|
|
}
|
|
|
|
return (struct rating_score){total_rating, total_score};
|
|
}
|
|
|
|
int64_t _2024_day10_part1(const char * input, int length)
|
|
{
|
|
int stride = parse_stride(input, length);
|
|
int height = parse_height(input, length);
|
|
int width = stride - 1;
|
|
|
|
struct rating_score rs = find_trailheads(input, length, stride, width, height);
|
|
|
|
return rs.score;
|
|
}
|
|
|
|
int64_t _2024_day10_part2(const char * input, int length)
|
|
{
|
|
int stride = parse_stride(input, length);
|
|
int height = parse_height(input, length);
|
|
int width = stride - 1;
|
|
|
|
struct rating_score rs = find_trailheads(input, length, stride, width, height);
|
|
|
|
return rs.rating;
|
|
}
|