diff --git a/2020/17/input.txt b/2020/17/input.txt new file mode 100644 index 0000000..e0779e1 --- /dev/null +++ b/2020/17/input.txt @@ -0,0 +1,8 @@ +##.#...# +#..##... +....#..# +....#### +#.#....# +###.#.#. +.#.#.#.. +.#.....# \ No newline at end of file diff --git a/2020/17/part1.js b/2020/17/part1.js new file mode 100644 index 0000000..248bc5e --- /dev/null +++ b/2020/17/part1.js @@ -0,0 +1,96 @@ +const fs = require('fs'); +const textIn = fs.readFileSync('./input.txt', 'utf-8'); +const iterAmt = 6; + +// make a list of points to add at first +let startPoints = [] +// could do forEach() instead of map() but i already did it like this and it works +startGrid = textIn.split('\n').map((line, y) => line.split('').map((point, x) => { + if (point=='#') { + startPoints.push([iterAmt+x,iterAmt+y,iterAmt]) + } + return point=='#' +})); +// start with zero active cubes +let runningTotal = 0; +// create an empty pocket dimension +let p = new Pocket() +// add the points from the input +startPoints.forEach(point => add(...point, p)); + +for (let i = 0; i < iterAmt; i++) { + printLayer(p,iterAmt); + + // create a deep copy of the current state + let next = p.map(layer => layer.map(row => row.map(cube => {return{active:cube.active,nearby:cube.nearby}}))) + + // for every single cube in the pocket dimension + p.forEach((layer, z) => layer.forEach((row, y) => row.forEach((cube, x) => { + // apply the game of life rules using p and store in next + if (cube.active && (cube.nearby < 2 || cube.nearby > 3)) { + remove(x,y,z,p,next) + } else if (!cube.active && (cube.nearby == 3)) { + add(x,y,z,p,next) + } + }))) + + p = next; +} + +console.log(runningTotal); + +// ------------------------------- + +function printLayer(pocket, layer) { + console.log( pocket[layer].reduce((a,b)=>a+b.reduce((c,d)=>c+(d.active?'\x1b[36m':'\x1b[0m')+(d.nearby.toString().length==1?'0':'')+d.nearby,'')+'\n','')) +} + +// returns empty pocket dimension +function Pocket () { + let pocket = []; + for (let z = 0; z < iterAmt*2+1; z++) { + let layer = [] + for (let y = 0; y < iterAmt*2+startGrid.length; y++) { + let row = [] + row = Array(iterAmt*2 + startGrid[0].length).fill(0).map(()=>{return{active:false,nearby:0}}) + layer.push(row) + } + pocket.push(layer) + } + return pocket +} + + +function add (x,y,z,before,after=before) { + if (before[z][y][x].active) return before; // if it's already active, do nothing + runningTotal++; + after[z][y][x].active = true; + // for every cube near the one we just added + for (let layer = Math.max(z-1, 0); layer <= Math.min(z+1, before.length-1); layer++) { + for (let row = Math.max(y-1, 0); row <= Math.min(y+1, before[0].length-1); row++) { + for (let col = Math.max(x-1, 0); col <= Math.min(x+1, before[0][0].length-1); col++) { + // but not the one we just added + if (layer == z && row == y && col == x) continue; + // there now is one more nearby cube + after[layer][row][col].nearby++ + } + } + } + return after; +} + +// add and remove could be combined into one function but i did it like this and it works +function remove (x,y,z,before,after=before) { + if (!before[z][y][x].active) return before; + runningTotal--; + after[z][y][x].active = false; + for (let layer = Math.max(z-1, 0); layer <= Math.min(z+1, before.length-1); layer++) { + for (let row = Math.max(y-1, 0); row <= Math.min(y+1, before[0].length-1); row++) { + for (let col = Math.max(x-1, 0); col <= Math.min(x+1, before[0][0].length-1); col++) { + if (layer == z && row == y && col == x) continue; + after[layer][row][col].nearby-- + } + } + } + return after; +} \ No newline at end of file diff --git a/2020/17/part2.js b/2020/17/part2.js new file mode 100644 index 0000000..2022910 --- /dev/null +++ b/2020/17/part2.js @@ -0,0 +1,92 @@ +// luckily i built it so it was pretty easy to add a new dimension + +const fs = require('fs'); +const textIn = fs.readFileSync('./input.txt', 'utf-8'); +const iterAmt = 6; +let startPoints = [] +startGrid = textIn.split('\n').map((line, y) => line.split('').map((point, x) => { + if (point=='#') { + startPoints.push([iterAmt+x,iterAmt+y,iterAmt,iterAmt]) + } + return point=='#' +})); + +let runningTotal = 0; +let p = new Pocket() + +startPoints.forEach(point => add(...point, p)); + +for (let i = 0; i < iterAmt; i++) { + printLayer(p,iterAmt,iterAmt); + + let next = p.map(slice => slice.map(layer => layer.map(row => row.map(cube => {return{active:cube.active,nearby:cube.nearby}})))) + + p.forEach((slice, w) => slice.forEach((layer, z) => layer.forEach((row, y) => row.forEach((cube, x) => { + if (cube.active && (cube.nearby < 2 || cube.nearby > 3)) { + remove(x,y,z,w,p,next) + } else if (!cube.active && (cube.nearby == 3)) { + add(x,y,z,w,p,next) + } + })))) + + p = next; +} +console.log(runningTotal); + +function printLayer(pocket, slice, layer) { + console.log(pocket[slice][layer].reduce((a,b)=>a+b.reduce((c,d)=>c+(d.active?'\x1b[36m':'\x1b[0m')+(d.nearby.toString().length==1?'0':'')+d.nearby,'')+'\n','')) +} + +function Pocket () { + let pocket = []; + for (let w = 0; w < iterAmt*2+1; w++) { + let slice = [] + for (let z = 0; z < iterAmt*2+1; z++) { + let layer = [] + for (let y = 0; y < iterAmt*2+startGrid.length; y++) { + let row = [] + for (let x = 0; x < iterAmt*2+startGrid[0].length; x++) { + row.push({active:false,nearby:0}) + } + layer.push(row) + } + slice.push(layer) + } + pocket.push(slice) + } + return pocket +} + +function add (x,y,z,w,before,after=before) { + if (before[w][z][y][x].active) return before; + runningTotal++; + after[w][z][y][x].active = true; + for (let slice = Math.max(w-1, 0); slice <= Math.min(w+1, before.length-1); slice++) { + for (let layer = Math.max(z-1, 0); layer <= Math.min(z+1, before[0].length-1); layer++) { + for (let row = Math.max(y-1, 0); row <= Math.min(y+1, before[0][0].length-1); row++) { + for (let col = Math.max(x-1, 0); col <= Math.min(x+1, before[0][0][0].length-1); col++) { + if (slice == w && layer == z && row == y && col == x) continue; + after[slice][layer][row][col].nearby++ + } + } + } + } + return after; +} + +function remove (x,y,z,w,before,after=before) { + if (!before[w][z][y][x].active) return before; + runningTotal--; + after[w][z][y][x].active = false; + for (let slice = Math.max(w-1, 0); slice <= Math.min(w+1, before.length-1); slice++) { + for (let layer = Math.max(z-1, 0); layer <= Math.min(z+1, before[0].length-1); layer++) { + for (let row = Math.max(y-1, 0); row <= Math.min(y+1, before[0][0].length-1); row++) { + for (let col = Math.max(x-1, 0); col <= Math.min(x+1, before[0][0][0].length-1); col++) { + if (slice == w && layer == z && row == y && col == x) continue; + after[slice][layer][row][col].nearby-- + } + } + } + } + return after; +} diff --git a/2020/17/test1.txt b/2020/17/test1.txt new file mode 100644 index 0000000..17630fd --- /dev/null +++ b/2020/17/test1.txt @@ -0,0 +1,3 @@ +.#. +..# +### \ No newline at end of file diff --git a/README.md b/README.md index caa7e09..221b267 100644 --- a/README.md +++ b/README.md @@ -57,3 +57,4 @@ if (advent) { 14. [:star: :star:](https://adventofcode.com/2020/day/14 "see puzzle") 15. [:star: :star:](https://adventofcode.com/2020/day/15 "see puzzle") 16. [:star: :star:](https://adventofcode.com/2020/day/16 "see puzzle") +17. [:star: :star:](https://adventofcode.com/2020/day/17 "see puzzle")