diff options
Diffstat (limited to '')
-rw-r--r-- | 2022/22-Monkey-Map/first.js | 144 |
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)); |