diff options
Diffstat (limited to '22.c')
-rw-r--r-- | 22.c | 71 |
1 files changed, 30 insertions, 41 deletions
@@ -40,7 +40,8 @@ direction_name(enum direction dir) struct elf { - long pos; + int x; + int y; enum direction dir; }; @@ -86,46 +87,33 @@ int elf_move(struct elf * elf, char const * map, int cols, int rows, enum map_type mtype, int distance) { while (distance > 0) { - int skip, wrap, base; + int dx = 0, dy = 0, elem; struct elf newelf; switch (elf->dir) { - case D_NORTH: - skip = -cols; - wrap = cols * rows; - break; - - case D_EAST: - skip = 1; - wrap = cols; - break; - - case D_SOUTH: - skip = cols; - wrap = cols * rows; - break; - - case D_WEST: - skip = -1; - wrap = cols; - break; - + case D_NORTH: dy = -1; break; + case D_SOUTH: dy = +1; break; + case D_EAST: dx = +1; break; + case D_WEST: dx = -1; break; default: fprintf(stderr, "Unexpected direction %d\n", elf->dir); return -1; } - base = (elf->pos / wrap) * wrap; - - newelf.pos = base + modulo(elf->pos + skip, wrap); + newelf.x = modulo(elf->x + dx, cols); + newelf.y = modulo(elf->y + dy, rows); newelf.dir = elf->dir; + elem = map[newelf.x + newelf.y * cols]; - if (map[newelf.pos] == ' ' || map[newelf.pos] == '\n') { + if (elem == ' ' || elem == '\n') { switch (mtype) { case M_FLAT: // Just keep going until we wrap around to a non-blank position - while (map[newelf.pos] == ' ' || map[newelf.pos] == '\n') - newelf.pos = base + modulo(newelf.pos + skip, wrap); + while (elem == ' ' || elem == '\n') { + newelf.x = modulo(newelf.x + dx, cols); + newelf.y = modulo(newelf.y + dy, rows); + elem = map[newelf.x + newelf.y * cols]; + } break; case M_NET: @@ -138,7 +126,7 @@ elf_move(struct elf * elf, char const * map, int cols, int rows, enum map_type m } } - switch (map[newelf.pos]) { + switch (elem) { case '.': *elf = newelf; --distance; @@ -149,7 +137,7 @@ elf_move(struct elf * elf, char const * map, int cols, int rows, enum map_type m break; default: - fprintf(stderr, "Unexpected map character %c\n", map[newelf.pos]); + fprintf(stderr, "Unexpected map character %c\n", elem); return -1; } } @@ -263,13 +251,14 @@ main(int argc, char ** argv) } // Set initial position - elf.pos = 0; + elf.x = 0; + elf.y = 0; elf.dir = D_EAST; - while (buf[elf.pos] != '.') - ++elf.pos; + while (elf.x < maxline && buf[elf.x] != '.') + ++elf.x; // Read and follow the movement instructions. - while (elf.pos >= 0 && (c = fgetc(stdin)) != EOF) { + while (elf.x >= 0 && (c = fgetc(stdin)) != EOF) { if (isdigit(c)) { distance[dlen++] = c; } @@ -277,9 +266,9 @@ main(int argc, char ** argv) distance[dlen] = '\0'; if (elf_move(&elf, buf, maxline, lines, mtype, atoi(distance)) != 0) - elf.pos = -1; + elf.x = -1; if (elf_turn(&elf, c) != 0) - elf.pos = -1; + elf.x = -1; dlen = 0; } @@ -287,7 +276,7 @@ main(int argc, char ** argv) // Cover last bit of distance, if any distance[dlen] = '\0'; if (elf_move(&elf, buf, maxline, lines, mtype, atoi(distance)) != 0) - elf.pos = -1; + elf.x = -1; break; } else { @@ -296,15 +285,15 @@ main(int argc, char ** argv) return -1; } } - if (elf.pos < 0) { + if (elf.x < 0) { free(buf); return -1; } // Done. - printf("Password is %ld (%ld,%ld,%d)\n", - 1000 * (1 + elf.pos / maxline) + 4 * (1 + elf.pos % maxline) + elf.dir, - (1 + elf.pos % maxline), (1 + elf.pos / maxline), elf.dir); + printf("Password is %d (%d,%d,%d)\n", + 1000 * (1 + elf.y) + 4 * (1 + elf.x) + elf.dir, + 1 + elf.x, 1 + elf.y, elf.dir); // Tidy and exit. free(buf); |