2023/day3: add part2 C solution
This commit is contained in:
parent
f47dbb6691
commit
959989750e
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
||||
*.bin
|
||||
*.d
|
||||
*.map
|
||||
*.out
|
@ -66,15 +66,9 @@ uint32_t ix_from_xy(uint8_t const * const start,
|
||||
return (stride * y + x);
|
||||
}
|
||||
|
||||
static const uint8_t symbols[] = {'@', '&', '=', '/', '-', '+', '%', '*', '$', '#'};
|
||||
|
||||
bool is_symbol(uint8_t const * const start,
|
||||
uint32_t const stride,
|
||||
uint32_t const x,
|
||||
uint32_t const y)
|
||||
bool is_symbol(uint8_t const c)
|
||||
{
|
||||
uint32_t const ix = ix_from_xy(start, stride, x, y);
|
||||
uint8_t const c = start[ix];
|
||||
static uint8_t const symbols[] = {'@', '&', '=', '/', '-', '+', '%', '*', '$', '#'};
|
||||
|
||||
for (uint32_t i = 0; i < (sizeof (symbols)) / (sizeof (*symbols)); i++) {
|
||||
if (c == symbols[i]) {
|
||||
@ -84,38 +78,90 @@ bool is_symbol(uint8_t const * const start,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_gear(uint8_t const c)
|
||||
{
|
||||
return c == '*';
|
||||
}
|
||||
|
||||
struct adjacency {
|
||||
uint32_t ix;
|
||||
int32_t count;
|
||||
int32_t neighbors[4];
|
||||
};
|
||||
|
||||
int32_t last_gear = 0;
|
||||
struct adjacency gears[512] = {0};
|
||||
|
||||
void update_gear_adjacencies(uint32_t gear_ix, uint32_t num)
|
||||
{
|
||||
for (int i = 0; i < (sizeof (gears)) / (sizeof (*gears)); i++) {
|
||||
if (i >= last_gear) {
|
||||
gears[last_gear++].ix = gear_ix;
|
||||
}
|
||||
|
||||
if (gears[i].ix == gear_ix) {
|
||||
if (gears[i].count < 4) {
|
||||
gears[i].neighbors[gears[i].count++] = num;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void adjacency_check(uint8_t const * const start,
|
||||
uint32_t const stride,
|
||||
int32_t const max_x,
|
||||
int32_t const max_y,
|
||||
int32_t const x,
|
||||
int32_t const y,
|
||||
uint32_t const num,
|
||||
bool * neighbor)
|
||||
{
|
||||
if (xy_in_bounds(max_x, max_y, x, y)) {
|
||||
uint32_t const ix = ix_from_xy(start, stride, x, y);
|
||||
uint8_t const c = start[ix];
|
||||
if (is_symbol(c))
|
||||
*neighbor = true;
|
||||
if (is_gear(c))
|
||||
update_gear_adjacencies(ix, num);
|
||||
}
|
||||
}
|
||||
|
||||
bool has_adjacent_symbol(uint8_t const * const start,
|
||||
uint32_t const stride,
|
||||
int32_t const max_x,
|
||||
int32_t const max_y,
|
||||
int32_t const x,
|
||||
int32_t const y,
|
||||
int32_t const digits)
|
||||
uint32_t const num,
|
||||
int32_t const digits
|
||||
)
|
||||
{
|
||||
bool neighbor = false;
|
||||
|
||||
/* check top/bottom/diagonals */
|
||||
for (int32_t xi = x - 1; xi <= x + digits; xi++) {
|
||||
if (xy_in_bounds(max_x, max_y, xi, y - 1)) {
|
||||
if (is_symbol(start, stride, xi, y - 1))
|
||||
return true;
|
||||
}
|
||||
if (xy_in_bounds(max_x, max_y, xi, y + 1)) {
|
||||
if (is_symbol(start, stride, xi, y + 1))
|
||||
return true;
|
||||
}
|
||||
adjacency_check(start, stride, max_x, max_y, xi, y + 1, num, &neighbor);
|
||||
adjacency_check(start, stride, max_x, max_y, xi, y - 1, num, &neighbor);
|
||||
}
|
||||
|
||||
/* check left/right side */
|
||||
if (xy_in_bounds(max_x, max_y, x + digits, y)) {
|
||||
if (is_symbol(start, stride, x + digits, y))
|
||||
return true;
|
||||
}
|
||||
adjacency_check(start, stride, max_x, max_y, x + digits, y, num, &neighbor);
|
||||
adjacency_check(start, stride, max_x, max_y, x - 1 , y, num, &neighbor);
|
||||
|
||||
if (xy_in_bounds(max_x, max_y, x - 1, y)) {
|
||||
if (is_symbol(start, stride, x - 1, y))
|
||||
return true;
|
||||
}
|
||||
return neighbor;
|
||||
}
|
||||
|
||||
return false;
|
||||
uint64_t part2_mac(void)
|
||||
{
|
||||
uint64_t mac = 0;
|
||||
for (int i = 0; i < last_gear; i++) {
|
||||
if (gears[i].count == 2) {
|
||||
mac += (uint64_t)gears[i].neighbors[0] * (uint64_t)gears[i].neighbors[1];
|
||||
}
|
||||
}
|
||||
return mac;
|
||||
}
|
||||
|
||||
void solve(uint8_t const * const start,
|
||||
@ -146,12 +192,18 @@ void solve(uint8_t const * const start,
|
||||
max_y,
|
||||
x,
|
||||
y,
|
||||
(int32_t)digits);
|
||||
num,
|
||||
(int32_t)digits
|
||||
);
|
||||
if (has)
|
||||
sum += num;
|
||||
}
|
||||
|
||||
printf("part1 sum: %d\n", sum);
|
||||
|
||||
printf("part2:\n");
|
||||
printf(" gears : %d\n", last_gear);
|
||||
printf(" answer: %ld\n", part2_mac());
|
||||
}
|
||||
|
||||
int main(void)
|
Loading…
x
Reference in New Issue
Block a user