summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--22.c71
1 files changed, 30 insertions, 41 deletions
diff --git a/22.c b/22.c
index 83da420..2a47a79 100644
--- a/22.c
+++ b/22.c
@@ -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);