day 25: code cleanup

This commit is contained in:
2022-09-08 21:08:49 +02:00
parent 5da5adb8bf
commit 721f9da54e

View File

@@ -17,12 +17,25 @@
#include <errno.h> #include <errno.h>
#include "debug.h" #include "debug.h"
#include "bits.h"
#define SWAP(x, y) do { typeof(x) __x = x; x = y; y = __x; } while (0)
#define EAST '>'
#define SOUTH 'v'
#define EMPTY '.'
struct map { struct map {
int ncols, nrows; uint ncols, nrows;
char *cur, *next; char *cur, *next;
}; };
struct move {
uchar r, c;
uchar r1, c1;
uchar dir;
};
/** /**
* mapc - gives address of cuncumber at position (row, col) * mapc - gives address of cuncumber at position (row, col)
* @ptr: char array * @ptr: char array
@@ -37,25 +50,28 @@ static inline char *mapc(char *p, int ncols, int row, int col)
return p + row * (ncols + 1) + col; return p + row * (ncols + 1) + col;
} }
/* static void print_map(struct map *map, int details)
* static void print_map(struct map *map)
* {
* printf("map: cols=%d rows=%d\ncur:\n%snext:\n%s",
* map->ncols, map->nrows, map->cur, map->next);
* }
*/
static inline int maybe_move(char *cur, char *next, int ncols,
char dir,
int r, int c, int r1, int c1)
{ {
int ret = 0; if (details) {
if (*mapc(cur, ncols, r, c) == dir && *mapc(cur, ncols, r1, c1) == '.') { log(2, "map: cols=%d rows=%d\ncur:\n%snext:\n%s",
*mapc(next, ncols, r, c) = '.'; map->ncols, map->nrows, map->cur, map->next);
*mapc(next, ncols, r1, c1) = dir; } else {
log(2, "cur:\n%s\n", map->cur);
}
}
static inline int maybe_move(struct map *map, struct move m)
{
int ret = 0, ncols = map->ncols;
char *cur = map->cur, *next = map->next;
if (*mapc(cur, ncols, m.r, m.c) == m.dir
&& *mapc(cur, ncols, m.r1, m.c1) == EMPTY) {
*mapc(next, ncols, m.r, m.c) = EMPTY;
*mapc(next, ncols, m.r1, m.c1) = m.dir;
ret = 1; ret = 1;
} else { } else {
*mapc(next, ncols, r, c) = *mapc(cur, ncols, r, c); *mapc(next, ncols, m.r, m.c) = *mapc(cur, ncols, m.r, m.c);
} }
return ret; return ret;
} }
@@ -63,26 +79,35 @@ static inline int maybe_move(char *cur, char *next, int ncols,
static int step(struct map *map) static int step(struct map *map)
{ {
int moves = 0, ncols = map->ncols, nrows = map->nrows; int moves = 0, ncols = map->ncols, nrows = map->nrows;
char *cur = map->cur, *next = map->next; struct move m;
/* move east */ /* move east */
for (int r = 0; r < nrows; r++) { m.dir = EAST;
for (int c = 0; c < ncols; ++c) { for (m.r = 0; m.r < nrows; ++m.r) {
if (maybe_move(cur, next, ncols, '>', r, c, r, (c + 1) % ncols)) { m.r1 = m.r;
for (m.c = 0; m.c < ncols; ++m.c) {
m.c1 = (m.c + 1) % ncols;
if (maybe_move(map, m)) {
moves++; moves++;
c++; m.c++;
} }
} }
} }
/* move south - here we move data from next to cur */
for (int c = 0; c < ncols; ++c) { /* move south - here we move data from next to cur (by swapping them) */
for (int r = 0; r < nrows; r++) { SWAP(map->cur, map->next);
if (maybe_move(next, cur, ncols, 'v', r, c, (r + 1) % nrows, c)) { m.dir = SOUTH;
for (m.c = 0; m.c < ncols; ++m.c) {
m.c1 = m.c;
for (m.r = 0; m.r < nrows; ++m.r) {
m.r1 = (m.r + 1) % nrows;
if (maybe_move(map, m)) {
moves++; moves++;
r++; m.r++;
} }
} }
} }
SWAP(map->cur, map->next);
return moves; return moves;
} }
@@ -98,11 +123,17 @@ static struct map *read_input()
if (map) { if (map) {
map->cur = NULL; map->cur = NULL;
/* read whole input */ /* read whole input, we will keep '\n' and avoit useless splitting */
buflen = getdelim(&map->cur, &alloc, '\0', stdin); buflen = getdelim(&map->cur, &alloc, '\0', stdin);
map->next = strdup(map->cur); map->next = strdup(map->cur);
map->ncols = strchr(map->cur, '\n') - map->cur; map->ncols = strchr(map->cur, '\n') - map->cur;
map->nrows = buflen / (map->ncols + 1); /* we suppose there is nothing after the last input data last line
* Therefore last char of input is '\n', at position (bufflen - 1)
*/
map->nrows = (buflen - 1) / map->ncols;
log(2, "buflen=%ld ncols=%d nrows=%d lastnl=%ld\n", buflen, map->ncols,
map->nrows, strrchr(map->cur, '\n') - map->cur);
} }
return map; return map;
} }
@@ -115,7 +146,10 @@ static int usage(char *prg)
int main(int ac, char **av) int main(int ac, char **av)
{ {
int opt, part = 1, moves, cur=1; int opt, part = 1;
struct map *map;
int moves, cur = 1;
while ((opt = getopt(ac, av, "d:p:")) != -1) { while ((opt = getopt(ac, av, "d:p:")) != -1) {
switch (opt) { switch (opt) {
case 'd': case 'd':
@@ -123,9 +157,9 @@ int main(int ac, char **av)
break; break;
case 'p': /* 1 or 2 */ case 'p': /* 1 or 2 */
part = atoi(optarg); part = atoi(optarg);
if (part < 1 || part > 2) if (part == 1 || part == 2)
return usage(*av);
break; break;
/* fall through */
default: default:
return usage(*av); return usage(*av);
} }
@@ -133,10 +167,13 @@ int main(int ac, char **av)
if (optind < ac) if (optind < ac)
return usage(*av); return usage(*av);
struct map *map = read_input(); if ((map = read_input())) {
if (map) while ((moves = step(map))) {
while ((moves = step(map)))
cur++; cur++;
log(2, "+++ after step %d\n", cur);
print_map(map, 0);
}
}
printf("%s : res=%d\n", *av, cur); printf("%s : res=%d\n", *av, cur);