commit d522cbdc3ea411ff6ed51dc2cc5859eeef79d577
parent e7d27a87e980ff7cda7665f5465b74cec156b0b2
Author: finwo <finwo@pm.me>
Date: Fri, 23 Dec 2022 15:36:41 +0100
2022/22 solution
Diffstat:
2 files changed, 276 insertions(+), 0 deletions(-)
diff --git a/2022/day-22/index.js b/2022/day-22/index.js
@@ -0,0 +1,262 @@
+const fs = require('fs');
+
+function drawMap(map) {
+ for(const row of map) {
+ for(let i=0; i<row.length; i++) {
+ process.stdout.write(directionChars[row[i]] || ' ');
+ }
+ process.stdout.write('\n');
+ }
+}
+
+function mod(n, m) {
+ return ((n%m)+m)%m;
+}
+
+function move(position, movement) {
+ return [
+ position[0] + movement[0],
+ position[1] + movement[1],
+ ];
+}
+
+// Fetch map
+const lines = fs.readFileSync('input', 'utf-8')
+// const lines = fs.readFileSync('sample', 'utf-8')
+ .trimEnd()
+ .split('\n');
+
+// Fetch directions
+const path = lines.pop()
+ .match(/(\d+|L|R)/g)
+ .map(stmt => isNaN(stmt) ? stmt : parseInt(stmt))
+lines.pop();
+
+let mapwidth = lines
+ .map(line => line.length)
+ .reduce((r,a) => Math.max(r,a), 0)
+
+// Map map into something usable
+for(let i=0; i<lines.length; i++) {
+ lines[i] = lines[i]
+ .split('')
+ .map(c => ({'.':4,'#':5}[c]));
+}
+
+// Define movements of directions
+const directions = [
+ [ 1, 0 ], // right
+ [ 0, 1 ], // down
+ [ -1, 0 ], // left
+ [ 0, -1 ], // up
+];
+const directionChars = ['>','v','<','^','.','#'];
+
+// How to wrap for step 1
+function positionStep1(map, position, movement, fallback) {
+ fallback = fallback || position;
+ let newpos = [...position];
+ let stat = lines[newpos[1]][newpos[0]];
+
+ // Move until non-undefined
+ do {
+ newpos = move(newpos, movement);
+ newpos[1] = mod(newpos[1], lines.length);
+ newpos[0] = mod(newpos[0], mapwidth);
+ stat = lines[newpos[1]][newpos[0]];
+ } while('undefined' === typeof stat);
+
+ // Return fallback if blocked
+ if (stat == 5) return [...fallback];
+ // Return new position, as it's available
+ return newpos;
+}
+
+const Dir = {
+ left: '-10',
+ right: '10',
+ up: '0-1',
+ down: '01',
+};
+
+// Cube shape
+// A-----B-----C
+// | | |
+// | a | b |
+// | | |
+// D-----E-----F
+// | |
+// | c |
+// | |
+// D-----G-----F
+// | | |
+// | d | e |
+// | | |
+// A-----H-----C
+// | |
+// | f |
+// | |
+// B-----C
+
+// Calculate wrapping method for step 2
+// Splits into 9 surfaces (manual edge wrapping)
+const surfaceSize = lines[0].length / 3;
+const x=0, y=1;
+function positionStep2(map, position, movement) {
+ let newpos = move(position, movement);
+ let aDir = movement.join('');
+ let newdir = directions.indexOf(movement);
+
+ // AB, a > f
+ if (position[x] >= 50 && position[x] < 100 && position[y] == 0 && aDir == Dir.up) {
+ newpos = [0, position[x] - 50 + 150];
+ newdir = 0; // right
+ }
+ // BC, b > f
+ if (position[x] >= 100 && position[x] < 150 && position[y] == 0 && aDir == Dir.up) {
+ newpos = [ position[x] - 100, 199 ];
+ newdir = 3; // up
+ }
+ // AD, a > d
+ if (position[x] == 50 && position[y] < 50 && aDir == Dir.left) {
+ newpos = [ 0, 149 - position[y] ];
+ newdir = 0; // right
+ }
+ // CF, b > e
+ if (position[x] == 149 && position[y] < 50 && aDir == Dir.right) {
+ newpos = [position[x] - 50, 149 - position[y]];
+ newdir = 2; // left
+ }
+ // EF, b > c
+ if (position[x] >= 100 && position[y] == 49 && aDir == Dir.down) {
+ newpos = [99, position[x] - 50];
+ newdir = 2; // left
+ }
+ // DG, c > d
+ if (position[x] == 50 && position[y] >= 50 && position[y] < 100 && aDir == Dir.left) {
+ newpos = [position[y] - 50, 100];
+ newdir = 1; // down
+ }
+ // EF, c > b
+ if (position[x] == 99 && position[y] >= 50 && position[y] < 100 && aDir == Dir.right) {
+ newpos = [position[y] + 50, 49];
+ newdir = 3; // up
+ }
+ // DG, d > c
+ if (position[x] < 50 && position[y] == 100 && aDir == Dir.up) {
+ newpos = [50, position[x] + 50];
+ newdir = 0; // right
+ }
+ // AD, d > a
+ if (position[x] == 0 && position[y] >= 100 && position[y] < 150 && aDir == Dir.left) {
+ newpos = [50, 149 - position[y]];
+ newdir = 0; // right
+ }
+ // CF, e > b
+ if (position[x] == 99 && position[y] >= 100 && position[y] < 150 && aDir == Dir.right) {
+ newpos = [149, 149 - position[y]];
+ newdir = 2; // left
+ }
+ // CH, e > f
+ if (position[x] >= 50 && position[x] < 100 && position[y] == 149 && aDir == Dir.down) {
+ newpos = [49, position[x] + 100];
+ newdir = 2; // left
+ }
+ // AB, f > a
+ if (position[x] == 0 && position[y] >= 150 && aDir == Dir.left) {
+ newpos = [position[y] - 100, 0];
+ newdir = 1; // down
+ }
+ // CH, f > e
+ if (position[x] == 49 && position[y] >= 150 && aDir == Dir.right) {
+ newpos = [position[y] - 100, 149];
+ newdir = 3; // up
+ }
+ // BC, f > b
+ if (position[x] < 50 && position[y] == 199 && aDir == Dir.down) {
+ newpos = [position[x] + 100, 0];
+ newdir = 1; // down
+ }
+
+ // Revert if we ran into a wall
+ const stat = lines[newpos[y]][newpos[x]];
+ if (stat == 5) {
+ newpos = [...position];
+ newdir = directions.indexOf(movement);
+ }
+
+ return [newpos, newdir];
+}
+
+
+
+// Define our character's position
+const characters = [
+ // {
+ // pos: [
+ // Math.min(
+ // lines[0].indexOf(4),
+ // lines[0].indexOf(5),
+ // ),
+ // 0,
+ // ],
+ // dir: 0,
+ // mv() {
+ // this.pos = positionStep1(lines, this.pos, directions[this.dir]);
+ // }
+ // },
+ {
+ pos: [
+ Math.min(
+ lines[0].indexOf(4),
+ lines[0].indexOf(5),
+ ),
+ 0,
+ ],
+ surface: surfaceSize == 12 ?
+ [ 2, 0 ] :
+ [ 1, 0 ],
+ dir: 0,
+ mv() {
+ let [pos,dir] = positionStep2(lines, this.pos, directions[this.dir]);
+ this.pos = pos;
+ this.dir = dir;
+ }
+ },
+];
+
+// Go over the instructions
+for(let stmt of path) {
+ for(const character of characters) {
+ lines[character.pos[1]][character.pos[0]] = character.dir;
+ if(isNaN(stmt)) {
+ const c = stmt == 'R' ? 1 : -1;
+ character.dir = mod(character.dir + c, directions.length);
+ lines[character.pos[1]][character.pos[0]] = character.dir;
+ } else {
+ // Move along
+ for(let i=0; i<stmt; i++) {
+ character.mv();
+ lines[character.pos[1]][character.pos[0]] = character.dir;
+ }
+ }
+ }
+}
+
+drawMap(lines);
+
+// Output characters and their password
+for(let character of characters) {
+ console.log({ character, password: ((character.pos[1]+1)*1000) + ((character.pos[0]+1)*4) + character.dir });
+}
+
+// let position = [
+// 0
+// ];
+// let direction = 0;
+
+
+
+
+
+// process.stdout.write(input);
diff --git a/2022/day-22/sample b/2022/day-22/sample
@@ -0,0 +1,14 @@
+ ...#
+ .#..
+ #...
+ ....
+...#.......#
+........#...
+..#....#....
+..........#.
+ ...#....
+ .....#..
+ .#......
+ ......#.
+
+10R5L5R10L4R5L5