2022 day 14 (C): final version. Too hacky for me...

This commit is contained in:
2023-03-18 17:30:26 +01:00
parent d1cf8d96b8
commit 5fc204744a
3 changed files with 48 additions and 109 deletions

View File

@@ -287,3 +287,17 @@ aoc-c: res=5843
aoc-c: res=26289 aoc-c: res=26289
time: 0:00.00 real, 0.00 user, 0.00 sys time: 0:00.00 real, 0.00 user, 0.00 sys
context-switch: 1+1, page-faults: 0+190 context-switch: 1+1, page-faults: 0+190
=========================================
================= day14 =================
=========================================
+++++++++++++++++ part 1
aoc-c: res=665
time: 0:00.00 real, 0.00 user, 0.00 sys
context-switch: 0+1, page-faults: 0+109
+++++++++++++++++ part 2
aoc-c: res=25434
time: 0:00.00 real, 0.00 user, 0.00 sys
context-switch: 0+1, page-faults: 0+121

View File

@@ -32,7 +32,6 @@ typedef enum { /* map cells */
EMPTY = '.', EMPTY = '.',
STONE = '#', STONE = '#',
SAND = 'o', SAND = 'o',
CURR = 'v'
} type_t; } type_t;
typedef struct segment { typedef struct segment {
@@ -42,81 +41,36 @@ typedef struct segment {
LIST_HEAD(segments); LIST_HEAD(segments);
typedef struct map {
static struct map {
int xmin, xmax, ymin, ymax; int xmin, xmax, ymin, ymax;
int size_x, size_y; int size_x, size_y;
int deltax, deltay; int deltax, deltay;
int dropcol; /* drop sand here */ int dropcol; /* drop sand here */
int dropped; /* number of sand units */ int dropped; /* number of sand units */
char *m; char *m;
} map = { } map_t;
.xmin = INT_MAX, .xmax = INT_MIN, .ymin = INT_MAX, .ymax = INT_MIN,
};
static void print_segments()
{
segment_t *cur;
log(2, "segments:\n");
list_for_each_entry(cur, &segments, list) {
log(2, "segment: (%d,%d) -> (%d,%d)\n", cur->x1, cur->y1, cur->x2, cur->y2);
}
}
#define XY(m, x, y) ((y) * m->size_x + (x)) #define XY(m, x, y) ((y) * m->size_x + (x))
#define P(m, x, y) (m->m[XY(m, (x), (y))]) #define P(m, x, y) (m->m[XY(m, (x), (y))])
static void print_map(struct map *m)
{
log_f(3, "xmin=%d xmax=%d ymin=%d ymax=%d deltax=%d deltay=%d sizex=%d sizey=%d\n",
m->xmin, m->xmax, m->ymin, m->ymax, m->deltax, m->deltay, m->size_x, m->size_y);
for (int skip=0; skip < m->dropcol + 3; ++skip)
log(3, " ");
log(3, "+\n");
for (int y = 0; y < m->size_y; ++y) {
log(3, "%02d ", y);
for (int x = 0; x < m->size_x; ++x) {
log(3, "%c", P(m, x, y));
}
log(3, "\n");
}
}
static int drop_sand(struct map *m, int x, int y) static int drop_sand(struct map *m, int x, int y)
{ {
int ret = 0, tmp; int ret = 0, tmp;
log_f(3, "x=%d y=%d\n", x, y); if (y >= m->ymax) /* part 1: nothing left under */
if (y >= m->ymax) /* nothing left under */
return INF; return INF;
if (P(m, x, y) != EMPTY) {
log(3, "ASSERT EMPTY(%d, %d) = %c\n", x, y, P(m, x, y));
exit(0);
}
//P(m, x, y) = CURR;
//print_map(m);
//P(m, x, y) = EMPTY;
//print_map(m);
log(4, "DOWN = (%d,%d)=%c %c\n", x, y+1, P(m, x, y+1), P(m, 7, 9));
if (P(m, x, y+1) == EMPTY) { /* down */ if (P(m, x, y+1) == EMPTY) { /* down */
//log(4, "zob1 %c!=%c\n", P(m, x, y+1), EMPTY);
if ((tmp = drop_sand(m, x, y+1)) < 0) if ((tmp = drop_sand(m, x, y+1)) < 0)
return INF; return INF;
ret += tmp; ret += tmp;
} }
if (//P(m, x-1, y) == EMPTY && if (P(m, x-1, y+1) == EMPTY) { /* left */
P(m, x-1, y+1) == EMPTY) { /* left */
//puts("zob2");
if ((tmp = drop_sand(m, x-1, y+1)) < 0) if ((tmp = drop_sand(m, x-1, y+1)) < 0)
return INF; return INF;
ret += tmp; ret += tmp;
} }
if (//P(m, x+1, y) == EMPTY && if (P(m, x+1, y+1) == EMPTY) { /* right */
P(m, x+1, y+1) == EMPTY) { /* right */
//puts("zob3");
if ((tmp = drop_sand(m, x+1, y+1)) < 0) if ((tmp = drop_sand(m, x+1, y+1)) < 0)
return INF; return INF;
ret += tmp; ret += tmp;
@@ -124,13 +78,8 @@ static int drop_sand(struct map *m, int x, int y)
/* the 3 lower adjacent cells are filled */ /* the 3 lower adjacent cells are filled */
P(m, x, y) = SAND; P(m, x, y) = SAND;
m->dropped++; m->dropped++;
if (y == 0) { if (y == 0) /* part 2 */
print_map(m);
return INF; return INF;
}
log(3, "DROPPED=%d\n", m->dropped);
if (!(m->dropped %100))
print_map(m);
return ret; return ret;
} }
@@ -144,25 +93,17 @@ static struct map *gen_map(struct map *m, int part)
m->deltax = m->xmin - 1; m->deltax = m->xmin - 1;
} else { } else {
m->ymax += 2; m->ymax += 2;
m->xmin = 500 - m->ymax; m->xmin = 500 - m->ymax - 1;
m->xmax = 500 + m->ymax; m->xmax = 500 + m->ymax + 1;
m->deltax = m->xmin - 1; m->deltax = m->xmin;
m->size_x = (m->xmax - m->xmin) + 3; m->size_x = (m->xmax - m->xmin);
//m->size_x = m->xmax; m->size_y = m->ymax + 3;
m->size_y = m->ymax + 2;
} }
size_t size = m->size_x * m->size_y;
//m->deltax = - 1;
//m->x1 -= m->deltax;
//m->y1 -= m->deltay;
//m->x2 -= m->deltax;
//m->y2 -= m->deltay,
m->dropcol = 500 - m->deltax; m->dropcol = 500 - m->deltax;
m->dropped = 0; m->dropped = 0;
m->m = malloc(size); m->m = malloc(m->size_x * m->size_y);
memset(m->m, '.', size); memset(m->m, '.', m->size_x * m->size_y);
list_for_each_entry(cur, &segments, list) { list_for_each_entry(cur, &segments, list) {
int x1 = cur->x1 - m->deltax, y1 = cur->y1 - m->deltay, int x1 = cur->x1 - m->deltax, y1 = cur->y1 - m->deltay,
x2 = cur->x2 - m->deltax, y2 = cur->y2 - m->deltay; x2 = cur->x2 - m->deltax, y2 = cur->y2 - m->deltay;
@@ -171,28 +112,19 @@ static struct map *gen_map(struct map *m, int part)
dy = y2 - y1 > 0 ? 1 : -1; dy = y2 - y1 > 0 ? 1 : -1;
else else
dx = x2 - x1 > 0 ? 1 : -1; dx = x2 - x1 > 0 ? 1 : -1;
log(3, "From (%d,%d) -> (%d,%d), dx=%d dy=%d <=> (%d,%d) -> (%d,%d)\n",
cur->x1, cur->y1, cur->x2, cur->y2, dx, dy, x1, y1, x2, y2 );
do { do {
log(3, "Setting (%d,%d)\n", x1, y1);
P(m, x1, y1) = '#'; P(m, x1, y1) = '#';
x1 += dx, y1 += dy; x1 += dx, y1 += dy;
} while (x1 != x2 || y1 != y2); } while (x1 != x2 || y1 != y2);
log(3, "Setting (%d,%d)\n", x2, y2);
P(m, x2, y2) = '#'; P(m, x2, y2) = '#';
log(2, "segment: (%d,%d) -> (%d,%d)\n", cur->x1, cur->y1, cur->x2, cur->y2);
} }
if (part == 2) if (part == 2)
for (int i = 0; i < m->xmax; ++i) for (int i = 0; i < m->size_x; ++i)
P(m, i, m->ymax) = STONE; P(m, m->xmin - m->deltax + i, m->ymax) = STONE;
log(3, "deltax=%d dx=%d dy=%d size=%lu drop=%d\n\n",
m->deltax, m->size_x, m->size_y, size, m->dropcol);
print_map(m);
return m; return m;
} }
static struct map *parse() static struct map *parse(map_t *m)
{ {
size_t alloc = 0; size_t alloc = 0;
ssize_t buflen; ssize_t buflen;
@@ -205,35 +137,27 @@ static struct map *parse()
i = 0; i = 0;
buf[--buflen] = 0; buf[--buflen] = 0;
cur = buf; cur = buf;
log(3, "INPUT: len=%lu <%s>\n", buflen, buf);
while (1) { while (1) {
scanned = sscanf(cur, "%d,%d ->%n", &x, &y, &n); scanned = sscanf(cur, "%d,%d ->%n", &x, &y, &n);
log(5, "scanned=%d n=%d x=%d y=%d\n", scanned, n, x, y);
if (scanned != 2) if (scanned != 2)
break; break;
map.xmin = min(x, map.xmin); m->xmin = min(x, m->xmin);
map.xmax = max(x, map.xmax); m->xmax = max(x, m->xmax);
map.ymin = min(y, map.ymin); m->ymin = min(y, m->ymin);
map.ymax = max(y, map.ymax); m->ymax = max(y, m->ymax);
if (i) { if (i) {
x1 = x2; x1 = x2;
y1 = y2; y1 = y2;
} }
x2 = x; x2 = x;
y2 = y; y2 = y;
if (!i) { /* first point */ if (!i) /* first point */
goto next; goto next;
}
segment = pool_get(pool_segment); segment = pool_get(pool_segment);
segment->x1 = x1; segment->x1 = x1;
segment->y1 = y1; segment->y1 = y1;
segment->x2 = x2; segment->x2 = x2;
segment->y2 = y2; segment->y2 = y2;
log(3, "segment: (%d,%d) -> (%d,%d)\n", x1, y1, x2, y2);
if (x1 != x2 && y1 != y2) {
log(3, "Ooops!\n");
exit(1);
}
list_add_tail(&segment->list, &segments); list_add_tail(&segment->list, &segments);
next: next:
i++; i++;
@@ -242,31 +166,29 @@ static struct map *parse()
break; break;
} }
} }
log(3, "xmin=%d xmax=%d ymin=%d ymax=%d\n", map.xmin, map.xmax, map.ymin, map.ymax); free(buf);
print_segments(); return m;
return &map;
} }
static int part1() static int doit(map_t *m, int part)
{ {
struct map *m = gen_map(parse(), 1); m = gen_map(parse(m), part);
drop_sand(m, m->dropcol, 0); drop_sand(m, m->dropcol, 0);
return m->dropped; return m->dropped;
} }
static int part2()
{
struct map *m = gen_map(parse(), 2);
drop_sand(m, m->dropcol, 0);
return m->dropped;
}
int main(int ac, char **av) int main(int ac, char **av)
{ {
int part = parseargs(ac, av); int part = parseargs(ac, av);
static map_t m;
m.xmin = INT_MAX; m.xmax = INT_MIN;
m.ymin = INT_MAX, m.ymax = INT_MIN;
pool_segment = pool_create("segment", 512, sizeof(segment_t)); pool_segment = pool_create("segment", 512, sizeof(segment_t));
printf("%s: res=%d\n", *av, part == 1? part1(): part2()); printf("%s: res=%d\n", *av, doit(&m, part));
free(m.m);
pool_destroy(pool_segment); pool_destroy(pool_segment);
exit(0); exit(0);
} }

View File

@@ -14,3 +14,6 @@
#### Advent of Code 2021 #### Advent of Code 2021
- `C`: All (days 1-25) - `C`: All (days 1-25)
#### Advent of Code 2022
- `C`: All (days 1-14)