aboutsummaryrefslogtreecommitdiff
path: root/2022/22-Monkey-Map/first.js
diff options
context:
space:
mode:
Diffstat (limited to '2022/22-Monkey-Map/first.js')
-rw-r--r--2022/22-Monkey-Map/first.js144
1 files changed, 144 insertions, 0 deletions
diff --git a/2022/22-Monkey-Map/first.js b/2022/22-Monkey-Map/first.js
new file mode 100644
index 0000000..5189032
--- /dev/null
+++ b/2022/22-Monkey-Map/first.js
@@ -0,0 +1,144 @@
+import * as fs from 'fs';
+
+class Line {
+ constructor(line) {
+ this.x = 0;
+ for(let i=0; i<line.length; ++i) {
+ if (line[i] == ' ') ++this.x;
+ }
+ this.data = line.slice(this.x);
+ }
+}
+
+const RIGHT=0, DOWN=1, LEFT=2, UP=3;
+
+class Walker {
+ constructor(lines, algo) {
+ this.lines = lines;
+ this.x = lines[0].x;
+ this.y = 0;
+ this.algo = algo;
+ this.direction=RIGHT;
+ this.height = this.lines.length;
+ }
+ isIn(x, y) {
+ if (y >= 0 && y < this.height) {
+ const line = this.lines[y];
+ if (x >= line.x && x < line.x + line.data.length) {
+ return true;
+ }
+ }
+ return false;
+ }
+ step(d) {
+ for(; d>0; --d) {
+ let line;
+ switch(this.direction) {
+ case RIGHT:
+ line = this.lines[this.y];
+ if (this.isIn(this.x+1, this.y)) {
+ if (line.data[this.x+1-line.x] === '.') {
+ ++this.x;
+ }
+ } else {
+ if (line.data[0] === '.') {
+ this.x = line.x;
+ }
+ }
+ break;
+ case LEFT:
+ line = this.lines[this.y];
+ if (this.isIn(this.x-1, this.y)) {
+ if (line.data[this.x-1-line.x] === '.') {
+ --this.x;
+ }
+ } else {
+ if (line.data[line.data.length - 1] === '.') {
+ this.x = line.x + line.data.length - 1;
+ }
+ }
+ break;
+ case DOWN:
+ if (this.isIn(this.x, this.y+1)) {
+ line = this.lines[this.y+1];
+ if (line.data[this.x-line.x] === '.') {
+ ++this.y;
+ }
+ } else {
+ let y = this.y;
+ while (this.isIn(this.x, y - 1)) {
+ --y;
+ }
+ line = this.lines[y];
+ if (line.data[this.x - line.x] === '.') {
+ this.y = y;
+ }
+ }
+ break;
+ case UP:
+ if (this.isIn(this.x, this.y-1)) {
+ line = this.lines[this.y-1];
+ if (line.data[this.x-line.x] === '.') {
+ --this.y;
+ }
+ } else {
+ let y = this.y;
+ while (this.isIn(this.x, y + 1)) {
+ ++y;
+ }
+ line = this.lines[y];
+ if (line.data[this.x - line.x] === '.') {
+ this.y = y;
+ }
+ }
+ break;
+ default: throw "unreachable";
+ }
+ }
+ }
+ walk() {
+ let d = 0;
+ for (let i=0; i<this.algo.length; ++i) {
+ const c = this.algo[i];
+ switch(c) {
+ case 'L':
+ this.step(d);
+ d = 0;
+ this.direction = (this.direction + 3) % 4;
+ break;
+ case 'R':
+ this.step(d);
+ d = 0;
+ this.direction = (this.direction +1) % 4;
+ break;
+ default:
+ d = d * 10 + parseInt(c);
+ }
+ }
+ this.step(d);
+ return 1000 * (this.y + 1) + 4 * (this.x + 1) + this.direction;
+ }
+}
+
+function load(filename) {
+ let lines = fs.readFileSync(filename, 'utf8').split('\n');
+ return new Walker(
+ lines.slice(0, -3).map(line => new Line(line)),
+ lines[lines.length - 2]
+ );
+}
+
+let example = load('example');
+let input = load('input');
+
+function solve(input) {
+ return input.walk();
+}
+
+const exampleOutput = solve(example);
+if (exampleOutput !== 6032) {
+ console.log('Example failed with ' + exampleOutput);
+ process.exit(1); // eslint-disable-line
+}
+
+console.log(solve(input));