diff --git a/.vscode/launch.json b/.vscode/launch.json index c20cb3f..129466c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,15 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "name": "Q17", + "program": "${workspaceFolder}/Q17.js", + "request": "launch", + "skipFiles": [ + "/**" + ], + "type": "pwa-node" + }, { "name": "Launch", "type": "go", diff --git a/17input.txt b/17input.txt new file mode 100644 index 0000000..db486cc --- /dev/null +++ b/17input.txt @@ -0,0 +1,8 @@ +...#..#. +..##.##. +..#..... +....#... +#.##...# +####..## +...##.#. +#.#.#... \ No newline at end of file diff --git a/Q17.js b/Q17.js new file mode 100644 index 0000000..72c8d49 --- /dev/null +++ b/Q17.js @@ -0,0 +1,192 @@ +const fs = require('fs') + +let list = [] + +function deepCopy(obj) { + if (typeof obj === 'object') { + if (Array.isArray(obj)) { + let l = obj.length; + let r = new Array(l); + for (let i = 0; i < l; i++) { + r[i] = deepCopy(obj[i]); + } + return r; + } else { + let r = {}; + r.prototype = obj.prototype; + for (let k in obj) { + r[k] = deepCopy(obj[k]); + } + return r; + } + } + return obj; +} + +function q17() { + let start = new Date() + makeList() + console.log(`makeList took ${(new Date() - start)}ms`) + start = new Date() + part1() + console.log(`q17part1 took ${(new Date() - start)}ms`) + start = new Date() + part2() + console.log(`q17part2 took ${(new Date() - start)}ms`) +} + +function makeList() { + const lines = fs.readFileSync('17input.txt').toString().split('\n') + + for (let i = 0; i < lines.length; i++) { + for (let j = 0; j < lines[i].trim().length; j++) { + if (!list[i]) { + list[i] = [] + } + + list[i][j] = lines[i][j] + } + } +} + +function activeNeighbors(arr, initialX, initialY, initialZ) { + let numActive = 0 + + for (let z = Math.max(initialZ - 1, 0); z <= Math.min(initialZ + 1, arr.length - 1); z++) { + for (let x = Math.max(initialX - 1, 0); x <= Math.min(initialX + 1, arr[z].length - 1); x++) { + for (let y = Math.max(initialY - 1, 0); y <= Math.min(initialY + 1, arr[z][x].length - 1); y++) { + if (z === initialZ && x === initialX && y === initialY) { + continue + } + + if (arr[z][x][y] === '#') { + numActive++ + } + } + } + } + + return numActive +} + +function activeNeighbors4(arr, initialX, initialY, initialZ, initialW) { + let numActive = 0 + + for (let w = Math.max(initialW - 1, 0); w <= Math.min(initialW + 1, arr.length - 1); w++) { + for (let z = Math.max(initialZ - 1, 0); z <= Math.min(initialZ + 1, arr[w].length - 1); z++) { + for (let x = Math.max(initialX - 1, 0); x <= Math.min(initialX + 1, arr[w][z].length - 1); x++) { + for (let y = Math.max(initialY - 1, 0); y <= Math.min(initialY + 1, arr[w][z][x].length - 1); y++) { + if (w === initialW && z === initialZ && x === initialX && y === initialY) { + continue + } + + if (arr[w][z][x][y] === '#') { + numActive++ + } + } + } + } + } + + return numActive +} + +function expandArea(arr) { + let xLen = arr[0].length + let yLen = arr[0][0].length + let emptyX = Array.from('.'.repeat(yLen + 2)) + let emptyZ = Array.from({ length: xLen + 2 }, () => emptyX) + + for (let z = 0; z < arr.length; z++) { + for (let x = 0; x < arr[z].length; x++) { + arr[z][x].unshift('.') + arr[z][x].push('.') + } + + arr[z].unshift(emptyX) + arr[z].push(emptyX) + } + + arr.unshift(emptyZ) + arr.push(emptyZ) +} + +function expandArea4(arr) { + let zLen = arr[0].length + + for (let w = 0; w < arr.length; w++) { + expandArea(arr[w]) + } + + let emptyW = Array.from({ length: zLen + 2 }, () => arr[0][0]) + + arr.unshift(emptyW) + arr.push(emptyW) +} + +function part1() { + let current = [] + current[0] = deepCopy(list) + + for (let loops = 0; loops < 6; loops++) { + expandArea(current) + let copy = deepCopy(current) + + for (let z = 0; z < current.length; z++) { + for (let x = 0; x < current[z].length; x++) { + for (let y = 0; y < current[z][x].length; y++) { + let numActive = activeNeighbors(current, x, y, z) + if (current[z][x][y] === '#') { + if (numActive !== 2 && numActive !== 3) { + copy[z][x][y] = '.' + } + } else { + if (numActive === 3) { + copy[z][x][y] = '#' + } + } + } + } + } + + current = deepCopy(copy) + } + + console.log(`q17part1: answer=${current.flat(Infinity).filter(i => i === '#').length}`) +} + +function part2() { + let current = [] + current[0] = [] + current[0][0] = deepCopy(list) + + for (let loops = 0; loops < 6; loops++) { + expandArea4(current) + let copy = deepCopy(current) + + for (let w = 0; w < current.length; w++) { + for (let z = 0; z < current[w].length; z++) { + for (let x = 0; x < current[w][z].length; x++) { + for (let y = 0; y < current[w][z][x].length; y++) { + let numActive = activeNeighbors4(current, x, y, z, w) + if (current[w][z][x][y] === '#') { + if (numActive !== 2 && numActive !== 3) { + copy[w][z][x][y] = '.' + } + } else { + if (numActive === 3) { + copy[w][z][x][y] = '#' + } + } + } + } + } + } + + current = deepCopy(copy) + } + + console.log(`q17part2: answer=${current.flat(Infinity).filter(i => i === '#').length}`) +} + +q17() \ No newline at end of file