3d12's recent activity
-
Comment on Paramount Plus and Showtime become ‘Paramount Plus with Showtime’ in ~tv
-
Comment on This shall be my last post about MUD games in ~games
3d12 Yeah, that's the site for ATS. They've got ship systems, some kind of commodity-based economy, and automated trading vessels going between stations; lots of really interesting mechanics which lend...Yeah, that's the site for ATS. They've got ship systems, some kind of commodity-based economy, and automated trading vessels going between stations; lots of really interesting mechanics which lend themselves well to players trying to generate their own content instead of having it randomly generated for them.
The social interaction is difficult sometimes, yeah. It's especially hard to get people onto the same timeframe for multiple scenes over an arc. But it just takes getting involved and putting yourself out there, just like any other community.
-
Comment on This shall be my last post about MUD games in ~games
3d12 Great write-up, lou! I used to be really into MU* games, spending most of that time on a Star Trek MUSH around 2009. What really struck me about that type of game is the freedom and creativity...Great write-up, lou!
I used to be really into MU* games, spending most of that time on a Star Trek MUSH around 2009. What really struck me about that type of game is the freedom and creativity allowed in building and describing things.
As an analogy, some games will give me color sliders to change the RGB values of my character's armor. But no game (that I know of) gives me the ability to import my own meshes and textures to make my armor look like literally whatever I want. That's the kind of freedom given to text.
Aside from just description, you make an excellent point about mechanics. The MUSH I played on used Aspace (originally from and still used by Among the Stars TrekMUSH) and that system is so incredible from a ship systems and command perspective. Easily the most fun I've had piloting a spaceship in any game.
-
Comment on Advent of Code 2022 post-mortem discussion in ~comp.advent_of_code
3d12 Confirmed, there is no day 26. Instead, how about a brief post-mortem from participants? Favorite/least favorite problems, any interesting workarounds, or something new you learned? I struggled...Confirmed, there is no day 26. Instead, how about a brief post-mortem from participants? Favorite/least favorite problems, any interesting workarounds, or something new you learned?
I struggled immensely with day 15, and that threw my rhythm off completely for the rest of the event. I also didn't bother posting any of my solutions in the threads this year, but since my wife is now learning Python, I tried doing the problems in Python so she could follow along. I took much better advantage of list comprehension this time, to great effect too, since I liked the map() functionality of Javascript so much when I used that last year.
My favorite problem this year was the CRT display one (day 10) just because I love the problems with a visual solution (see also: transparent origami, AoC 2021 Day 13)
My repo of solution code: https://github.com/3d12/adventofcode2022-py
I also admit I had to peek at the thread for day 13 to find the solution to part 2. My math skills were failing me and I tried a bunch of different modulo numbers but didn't even think of the lowest common multiple.
-
Comment on The next (monthly, one-month-long) Linux Upskill Challenge starts this Monday in ~comp
3d12 Thanks for bringing this up, Eric_the_Cerise :) I am also following along with this, but I don't feel like logging into reddit to participate. Will it be too noisy if we create daily threads to...Thanks for bringing this up, Eric_the_Cerise :) I am also following along with this, but I don't feel like logging into reddit to participate. Will it be too noisy if we create daily threads to share our progress on this event? Would weekly perhaps work better?
As for my day 1, I actually went ahead and added the SSH key for login on day 0 (setup) since Digital Ocean offers that instead of a password-based login. So I ended up getting a little ahead and not having much to do today. But I'm looking forward to learning more sysadmin stuff! Specifically, I'm not so good with systemd yet or networking & sockets, so I'm hoping this event will touch on those topics.
-
Comment on Day 13: Transparent Origami in ~comp.advent_of_code
3d12 Friggin' yeesh. With everyone saying how easy this year is compared to previous, it's no wonder I couldn't hang in this far in previous years. This did end up being a very fun (and visually...Friggin' yeesh. With everyone saying how easy this year is compared to previous, it's no wonder I couldn't hang in this far in previous years.
This did end up being a very fun (and visually pleasing!) problem once I worked out the kinks. I knew I'd get in trouble for "standardizing" my test folds to a centralized axis, so that did come back to bite me. But I went ahead and coded for all the folds since the problem implied that was the next step, and ended up getting some fun map/filter practice to backwardly-derive my answer to part 1.
Part 1
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function parseGrid(input) { let gridPoints = []; for (const line of input) { let regex = /(\d+),(\d+)/; let found = line.match(regex); if (found) { let pointX = parseInt(found[1]); let pointY = parseInt(found[2]); gridPoints.push({ x: pointX, y: pointY }); } } let foldInstructions = []; for (const line of input) { let regex = /fold along ([x|y])=(\d+)/; let found = line.match(regex); if (found) { let foldDirection = found[1]; let foldDistance = parseInt(found[2]); foldInstructions.push({ direction: foldDirection, distance: foldDistance }); } } return { gridPoints: gridPoints, foldInstructions: foldInstructions }; } function mapGrid(input) { let output = []; console.log("DEBUG: input.map(e => e.x) = " + input.map(e => e.x).sort((a,b) => b-a)[0]); let length = input.map(e => e.x).sort((a,b) => b-a)[0]; let depth = input.map(e => e.y).sort((a,b) => b-a)[0]; console.log("DEBUG: length = " + length + ", depth = " + depth); for (let y = 0; y <= depth; y++) { let currentLine = []; for (let x = 0; x <= length; x++) { if (input.filter(e => e.x === x).filter(e => e.y === y).length > 0) { currentLine.push('#'); } else { currentLine.push('.'); } } output.push(currentLine); } return output; } function foldGrid(input,direction,distance) { let output = []; if (direction === 'x') { let inputCopy = input.map(e => e); for (let row of inputCopy) { row[distance] = '|'; } console.log(inputCopy.map(e => e.join('')).join('\n')); for (let row of inputCopy) { let newRow = []; for (let i = 0; i < distance; i++) { let char1 = row[i]; let char2 = row[i+((distance-i)*2)]; if (char1 === '#' || char2 === '#') { newRow.push('#'); } else { newRow.push('.'); } } output.push(newRow); } } else if (direction === 'y') { let foldRow = []; for (let i = 0; i<input[distance].length; i++) { foldRow.push('-'); } let inputCopy = input.map(e => e); inputCopy[distance] = foldRow; console.log(inputCopy.map(e => e.join('')).join('\n')); for (let i = 0; i < distance; i++) { let currentRow = inputCopy[i]; let compareRow = []; let distanceOffset = i+((distance-i)*2); if (distanceOffset < inputCopy.length) { compareRow = inputCopy[i+((distance-i)*2)]; } else { compareRow = currentRow; } let newRow = []; for (let charIndex = 0; charIndex < currentRow.length; charIndex++) { let currentChar = currentRow[charIndex]; let compareChar = compareRow[charIndex]; if (currentChar === '#' || compareChar === '#') { newRow.push('#'); } else { newRow.push('.'); } } output.push(newRow); } } else { return new Exception("Invalid direction passed: " + direction); } return output; } (async function mainExecution() { await openFileForReading('input.txt'); let parsedGrid = parseGrid(inputArr); console.log(parsedGrid); let fold = 0; let foldedMap = mapGrid(parsedGrid.gridPoints); console.log("DEBUG: fold = " + fold + ", direction = " + parsedGrid.foldInstructions[0].direction + ", distance = " + parsedGrid.foldInstructions[0].distance); console.log(foldedMap.map(e => e.join('')).join('\n')); console.log(''); foldedMap = foldGrid( foldedMap, parsedGrid.foldInstructions[0].direction, parsedGrid.foldInstructions[0].distance ); // for (const instruction of parsedGrid.foldInstructions) { // fold++; // console.log("DEBUG: fold = " + fold + ", direction = " + instruction.direction + ", distance = " + instruction.distance); // foldedMap = foldGrid( // foldedMap, // instruction.direction, // instruction.distance // ); // console.log(''); // console.log(foldedMap.map(e => e.join('')).join('\n')); // console.log(''); // } let totalDots = foldedMap .filter(e => e.includes('#')) .map(e => e.filter(f => f === '#').length) .reduce((a,b) => a + b); console.log("Answer found! " + totalDots); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function parseGrid(input) { let gridPoints = []; for (const line of input) { let regex = /(\d+),(\d+)/; let found = line.match(regex); if (found) { let pointX = parseInt(found[1]); let pointY = parseInt(found[2]); gridPoints.push({ x: pointX, y: pointY }); } } let foldInstructions = []; for (const line of input) { let regex = /fold along ([x|y])=(\d+)/; let found = line.match(regex); if (found) { let foldDirection = found[1]; let foldDistance = parseInt(found[2]); foldInstructions.push({ direction: foldDirection, distance: foldDistance }); } } return { gridPoints: gridPoints, foldInstructions: foldInstructions }; } function mapGrid(input) { let output = []; console.log("DEBUG: input.map(e => e.x) = " + input.map(e => e.x).sort((a,b) => b-a)[0]); let length = input.map(e => e.x).sort((a,b) => b-a)[0]; let depth = input.map(e => e.y).sort((a,b) => b-a)[0]; console.log("DEBUG: length = " + length + ", depth = " + depth); for (let y = 0; y <= depth; y++) { let currentLine = []; for (let x = 0; x <= length; x++) { if (input.filter(e => e.x === x).filter(e => e.y === y).length > 0) { currentLine.push('#'); } else { currentLine.push('.'); } } output.push(currentLine); } return output; } function foldGrid(input,direction,distance) { let output = []; if (direction === 'x') { let inputCopy = input.map(e => e); for (let row of inputCopy) { row[distance] = '|'; } console.log(inputCopy.map(e => e.join('')).join('\n')); for (let row of inputCopy) { let newRow = []; for (let i = 0; i < distance; i++) { let char1 = row[i]; let char2 = row[i+((distance-i)*2)]; if (char1 === '#' || char2 === '#') { newRow.push('#'); } else { newRow.push('.'); } } output.push(newRow); } } else if (direction === 'y') { let foldRow = []; for (let i = 0; i<input[distance].length; i++) { foldRow.push('-'); } let inputCopy = input.map(e => e); inputCopy[distance] = foldRow; console.log(inputCopy.map(e => e.join('')).join('\n')); for (let i = 0; i < distance; i++) { let currentRow = inputCopy[i]; let compareRow = []; let distanceOffset = i+((distance-i)*2); if (distanceOffset < inputCopy.length) { compareRow = inputCopy[i+((distance-i)*2)]; } else { compareRow = currentRow; } let newRow = []; for (let charIndex = 0; charIndex < currentRow.length; charIndex++) { let currentChar = currentRow[charIndex]; let compareChar = compareRow[charIndex]; if (currentChar === '#' || compareChar === '#') { newRow.push('#'); } else { newRow.push('.'); } } output.push(newRow); } } else { return new Exception("Invalid direction passed: " + direction); } return output; } (async function mainExecution() { await openFileForReading('input.txt'); let parsedGrid = parseGrid(inputArr); console.log(parsedGrid); let fold = 0; let foldedMap = mapGrid(parsedGrid.gridPoints); console.log("DEBUG: fold = " + fold + ", direction = " + parsedGrid.foldInstructions[0].direction + ", distance = " + parsedGrid.foldInstructions[0].distance); console.log(foldedMap.map(e => e.join('')).join('\n')); for (const instruction of parsedGrid.foldInstructions) { fold++; console.log("DEBUG: fold = " + fold + ", direction = " + instruction.direction + ", distance = " + instruction.distance); foldedMap = foldGrid( foldedMap, instruction.direction, instruction.distance ); console.log(''); console.log(foldedMap.map(e => e.join('')).join('\n')); console.log(''); } })();
-
Comment on Day 12: Passage Pathing in ~comp.advent_of_code
3d12 Really bad. Like, over a minute? But, I didn't try it with all the console.log statements removed.Really bad. Like, over a minute? But, I didn't try it with all the console.log statements removed.
-
Comment on Day 12: Passage Pathing in ~comp.advent_of_code
3d12 Like others, I also stared at this problem for many minutes before writing any code. In fact, I thought about it so long, I fell asleep and decided to tackle it today instead. I'm not great at...Like others, I also stared at this problem for many minutes before writing any code. In fact, I thought about it so long, I fell asleep and decided to tackle it today instead.
I'm not great at recursive functions, so imagine my surprise when the problem circumvented my expectations (and the reason I parsed the upper-cased-ness of the letters into a boolean flag in part 1) which led to my business side coding kicking in, and implementing a horrible "exclusion rule" which is used both in the selection criteria, then again in the actual recursion step in part 2. Hey, at least it worked. ¯\_(ツ)_/¯
Part 1
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function parseCaves(input) { let cavesArr = []; for (const line of input) { let lineRegex = /(\w+)-(\w+)/; let found = line.match(lineRegex); let dest1 = found[1]; let dest2 = found[2]; console.log("DEBUG: line parsed, dest1 = " + dest1 + ", dest2 = " + dest2); let findDest1 = cavesArr.filter(e => e.name === dest1); if (findDest1.length === 0) { let multiplePassThrough = false; if (dest1 === dest1.toUpperCase()) { multiplePassThrough = true; } cavesArr.push({ name: dest1, leadsTo: [ dest2 ], multiplePassThrough: multiplePassThrough }); } else { findDest1[0].leadsTo.push(dest2); } let findDest2 = cavesArr.filter(e => e.name === dest2); if (findDest2.length === 0) { let multiplePassThrough = false; if (dest2 === dest2.toUpperCase()) { multiplePassThrough = true; } cavesArr.push({ name: dest2, leadsTo: [ dest1 ], multiplePassThrough: multiplePassThrough}); } else { findDest2[0].leadsTo.push(dest1); } } return cavesArr; } function findPaths(mapArr, startRoom=mapArr.filter(e => e.name === 'start')[0], currentPath=[], pathsArr=[]) { console.log("DEBUG: entering findPaths, startRoom is " + startRoom.name + " and currentPath is " + currentPath.map(e => e.name).join(',')); if (startRoom.name === 'end') { console.log("DEBUG: ending findPaths, found end room"); let tempPath = currentPath.map(e => e); tempPath.push(startRoom); pathsArr.push(tempPath); return pathsArr; } if (startRoom.name === 'start') { console.log("DEBUG: starting findPaths, found start room"); currentPath.push(startRoom); } let dests = startRoom.leadsTo; let destObjects = []; for (const dest of dests) { destObjects.push(mapArr.filter(e => e.name === dest)[0]); } let eligibleDests = destObjects.filter(e => (currentPath.filter(f => e.name === f.name).length === 0) || e.multiplePassThrough === true); //console.log("DEBUG: eligible dests: " + eligibleDests.map(e => e.name).join(',')); for (const dest of eligibleDests) { let tempPath = currentPath.map(e => e); if (dest.name != 'end') { tempPath.push(dest); } //console.log("DEBUG: about to recurse, startRoom = " + startRoom.name + ", dest = " + dest.name + ", currentPath = " + tempPath.map(e => e.name).join(',') + " and pathsArr = " + pathsArr.map(e => e.map(f => f.name).join(',')).join(';')) findPaths(mapArr, dest, tempPath, pathsArr); } return pathsArr; } (async function mainExecution() { await openFileForReading('input.txt'); let cavesArr = parseCaves(inputArr); console.log(cavesArr); let paths = findPaths(cavesArr); console.log(paths); console.log(paths.length); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function parseCaves(input) { let cavesArr = []; for (const line of input) { let lineRegex = /(\w+)-(\w+)/; let found = line.match(lineRegex); let dest1 = found[1]; let dest2 = found[2]; console.log("DEBUG: line parsed, dest1 = " + dest1 + ", dest2 = " + dest2); let findDest1 = cavesArr.filter(e => e.name === dest1); if (findDest1.length === 0) { let multiplePassThrough = false; if (dest1 === dest1.toUpperCase()) { multiplePassThrough = true; } cavesArr.push({ name: dest1, leadsTo: [ dest2 ], multiplePassThrough: multiplePassThrough }); } else { findDest1[0].leadsTo.push(dest2); } let findDest2 = cavesArr.filter(e => e.name === dest2); if (findDest2.length === 0) { let multiplePassThrough = false; if (dest2 === dest2.toUpperCase()) { multiplePassThrough = true; } cavesArr.push({ name: dest2, leadsTo: [ dest1 ], multiplePassThrough: multiplePassThrough}); } else { findDest2[0].leadsTo.push(dest1); } } return cavesArr; } function findPaths(mapArr, startRoom=mapArr.filter(e => e.name === 'start')[0], currentPath=[], pathsArr=[], smallRoomDoubled=false) { console.log("DEBUG: entering findPaths, startRoom is " + startRoom.name + ", smallRoomDoubled is " + smallRoomDoubled + ", and currentPath is " + currentPath.map(e => e.name).join(',')); if (startRoom.name === 'end') { console.log("DEBUG: ending findPaths, found end room"); let tempPath = currentPath.map(e => e); tempPath.push(startRoom); pathsArr.push(tempPath); return pathsArr; } if (startRoom.name === 'start') { console.log("DEBUG: starting findPaths, found start room"); currentPath.push(startRoom); } let dests = startRoom.leadsTo; let destObjects = []; for (const dest of dests) { destObjects.push(mapArr.filter(e => e.name === dest)[0]); } let eligibleDests = destObjects.filter(e => ( currentPath.filter(f => e.name === f.name).length === 0 || e.multiplePassThrough === true || ( e.name === e.name.toLowerCase() && currentPath.filter(f => e.name === f.name).length === 1 && smallRoomDoubled === false && e.name != 'start' && e.name != 'end' ) )); //console.log("DEBUG: eligible dests: " + eligibleDests.map(e => e.name).join(',')); for (const dest of eligibleDests) { let tempPath = currentPath.map(e => e); let tempSmallRoomDoubled = smallRoomDoubled; if (dest.name != 'end') { tempPath.push(dest); } if ( dest.name === dest.name.toLowerCase() && currentPath.filter(f => dest.name === f.name).length === 1 && tempSmallRoomDoubled === false && dest.name != 'start' && dest.name != 'end' ) { findPaths(mapArr, dest, tempPath, pathsArr, true); } else { //console.log("DEBUG: about to recurse, startRoom = " + startRoom.name + ", dest = " + dest.name + ", currentPath = " + tempPath.map(e => e.name).join(',') + " and pathsArr = " + pathsArr.map(e => e.map(f => f.name).join(',')).join(';')) findPaths(mapArr, dest, tempPath, pathsArr, smallRoomDoubled); } } return pathsArr; } (async function mainExecution() { await openFileForReading('input.txt'); let cavesArr = parseCaves(inputArr); console.log(cavesArr); let paths = findPaths(cavesArr); console.log(paths); console.log(paths.length); })();
-
Comment on Day 11: Dumbo Octopus in ~comp.advent_of_code
3d12 Yay for reusable functions! Just had to add diagonals to my findNeighbors function from day9, and it was ready to be re-used! On a side note, part 2's output was extremely visually satisfying to...Yay for reusable functions! Just had to add diagonals to my findNeighbors function from day9, and it was ready to be re-used! On a side note, part 2's output was extremely visually satisfying to me. :)
Oh! And I'm extremely proud of my solve time between the two parts. Part 2 only took +3m from part 1, because I was already returning the count of flashes from each iteration, and the comparison for that is a calculable constant!
Part 1
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function findNeighbors(x,y,octopusGrid) { let neighbors = []; let rowBoundary = octopusGrid.length-1; let colBoundary = octopusGrid[0].length-1; // left if (x-1 >= 0) { neighbors.push({ x: x-1, y: y }); } // right if (x+1 <= colBoundary) { neighbors.push({ x: x+1, y: y }); } // up if (y-1 >= 0) { neighbors.push({ x: x, y: y-1 }); } // down if (y+1 <= rowBoundary) { neighbors.push({ x: x, y: y+1 }); } // up-left if (x-1 >= 0 && y-1 >= 0) { neighbors.push({ x: x-1, y: y-1 }); } // up-right if (x+1 <= colBoundary && y-1 >= 0) { neighbors.push({ x: x+1, y: y-1 }); } // down-left if (x-1 >= 0 && y+1 <= rowBoundary) { neighbors.push({ x: x-1, y: y+1 }); } // down-right if (x+1 <= colBoundary && y+1 <= rowBoundary) { neighbors.push({ x: x+1, y: y+1 }); } return neighbors; } function simulateStep(octopusGrid) { let flashedThisStep = []; let newGrid = []; // serialize into objects for (let y = 0; y < octopusGrid.length; y++) { let currentRow = octopusGrid[y]; let newRow = []; for (let x = 0; x < currentRow.length; x++) { newRow.push({ numericValue: octopusGrid[y][x] }); } newGrid.push(newRow); } // increment every octopus' value by 1 for (let y = 0; y < newGrid.length; y++) { let currentRow = newGrid[y]; for (let x = 0; x < currentRow.length; x++) { newGrid[y][x].numericValue++; } } // check for flashes for (let y = 0; y < newGrid.length; y++) { let currentRow = newGrid[y]; for (let x = 0; x < currentRow.length; x++) { let currentOctopus = currentRow[x]; // on flash, if not already flashed this step if (currentOctopus.numericValue > 9 && flashedThisStep.filter(e => e.x === x && e.y === y).length === 0) { let flashesToResolve = [ { x: x, y: y } ]; while (flashesToResolve.length > 0) { //console.log("DEBUG: flashesToResolve = " + flashesToResolve.map(e => e.x + ',' + e.y).join(';')); let resolvingFlash = flashesToResolve.pop(); //console.log("DEBUG: " + resolvingFlash.x + "," + resolvingFlash.y + " (" + newGrid[resolvingFlash.y][resolvingFlash.x].numericValue + ") flashed"); // add to flashedThisStep flashedThisStep.push({ x: resolvingFlash.x, y: resolvingFlash.y }); let neighbors = findNeighbors(resolvingFlash.x,resolvingFlash.y,newGrid); //console.log("DEBUG: neighbors: " + neighbors.map(e => e.x + "," + e.y).join(';')); // increase all neighbors for (const neighbor of neighbors) { //console.log("DEBUG: increasing neighbor " + neighbor.x + "," + neighbor.y + " (" + newGrid[neighbor.y][neighbor.x].numericValue + ") -> (" + (newGrid[neighbor.y][neighbor.x].numericValue + 1) + ")"); newGrid[neighbor.y][neighbor.x].numericValue++; // check for flashes if (newGrid[neighbor.y][neighbor.x].numericValue > 9 && flashedThisStep.filter(e => e.x === neighbor.x && e.y === neighbor.y).length === 0 && flashesToResolve.filter(e => e.x === neighbor.x && e.y === neighbor.y).length === 0) { //console.log("DEBUG: adding " + neighbor.x + "," + neighbor.y + " to flashesToResolve"); // add to flashesToResolve flashesToResolve.push(neighbor); } } } } } } // all flashed octopi have their energy reset for (const flashed of flashedThisStep) { newGrid[flashed.y][flashed.x].numericValue = 0; } return { updatedGrid: newGrid.map(e => e.map(f => f.numericValue)), flashedThisStep: flashedThisStep }; } (async function mainExecution() { await openFileForReading('input.txt'); let octopusArr = []; let totalFlashes = 0; for (const line of inputArr) { let tempLine = []; for (const char of line) { tempLine.push(parseInt(char)); } octopusArr.push(tempLine); } //console.log(octopusArr.map(e => e.join('')).join('\n')); console.log("DEBUG: start of step 1: "); console.log(octopusArr.map(e => e.join('')).join('\n')); console.log("DEBUG: totalFlashes = " + totalFlashes); let updatedArr = simulateStep(octopusArr); totalFlashes += updatedArr.flashedThisStep.length; console.log("DEBUG: end of step 1: "); console.log(updatedArr.updatedGrid.map(e => e.join('')).join('\n')); console.log("DEBUG: totalFlashes = " + totalFlashes); for (let i = 0; i < 99; i++) { console.log("DEBUG: start of step " + (i+2) + ": "); console.log(updatedArr.updatedGrid.map(e => e.join('')).join('\n')); console.log("DEBUG: totalFlashes = " + totalFlashes); updatedArr = simulateStep(updatedArr.updatedGrid); totalFlashes += updatedArr.flashedThisStep.length; console.log("DEBUG: end of step " + (i+2) + ": "); console.log(updatedArr.updatedGrid.map(e => e.join('')).join('\n')); console.log("DEBUG: totalFlashes = " + totalFlashes); } })();
Part 2
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function findNeighbors(x,y,octopusGrid) { let neighbors = []; let rowBoundary = octopusGrid.length-1; let colBoundary = octopusGrid[0].length-1; // left if (x-1 >= 0) { neighbors.push({ x: x-1, y: y }); } // right if (x+1 <= colBoundary) { neighbors.push({ x: x+1, y: y }); } // up if (y-1 >= 0) { neighbors.push({ x: x, y: y-1 }); } // down if (y+1 <= rowBoundary) { neighbors.push({ x: x, y: y+1 }); } // up-left if (x-1 >= 0 && y-1 >= 0) { neighbors.push({ x: x-1, y: y-1 }); } // up-right if (x+1 <= colBoundary && y-1 >= 0) { neighbors.push({ x: x+1, y: y-1 }); } // down-left if (x-1 >= 0 && y+1 <= rowBoundary) { neighbors.push({ x: x-1, y: y+1 }); } // down-right if (x+1 <= colBoundary && y+1 <= rowBoundary) { neighbors.push({ x: x+1, y: y+1 }); } return neighbors; } function simulateStep(octopusGrid) { let flashedThisStep = []; let newGrid = []; // serialize into objects for (let y = 0; y < octopusGrid.length; y++) { let currentRow = octopusGrid[y]; let newRow = []; for (let x = 0; x < currentRow.length; x++) { newRow.push({ numericValue: octopusGrid[y][x] }); } newGrid.push(newRow); } // increment every octopus' value by 1 for (let y = 0; y < newGrid.length; y++) { let currentRow = newGrid[y]; for (let x = 0; x < currentRow.length; x++) { newGrid[y][x].numericValue++; } } // check for flashes for (let y = 0; y < newGrid.length; y++) { let currentRow = newGrid[y]; for (let x = 0; x < currentRow.length; x++) { let currentOctopus = currentRow[x]; // on flash, if not already flashed this step if (currentOctopus.numericValue > 9 && flashedThisStep.filter(e => e.x === x && e.y === y).length === 0) { let flashesToResolve = [ { x: x, y: y } ]; while (flashesToResolve.length > 0) { //console.log("DEBUG: flashesToResolve = " + flashesToResolve.map(e => e.x + ',' + e.y).join(';')); let resolvingFlash = flashesToResolve.pop(); //console.log("DEBUG: " + resolvingFlash.x + "," + resolvingFlash.y + " (" + newGrid[resolvingFlash.y][resolvingFlash.x].numericValue + ") flashed"); // add to flashedThisStep flashedThisStep.push({ x: resolvingFlash.x, y: resolvingFlash.y }); let neighbors = findNeighbors(resolvingFlash.x,resolvingFlash.y,newGrid); //console.log("DEBUG: neighbors: " + neighbors.map(e => e.x + "," + e.y).join(';')); // increase all neighbors for (const neighbor of neighbors) { //console.log("DEBUG: increasing neighbor " + neighbor.x + "," + neighbor.y + " (" + newGrid[neighbor.y][neighbor.x].numericValue + ") -> (" + (newGrid[neighbor.y][neighbor.x].numericValue + 1) + ")"); newGrid[neighbor.y][neighbor.x].numericValue++; // check for flashes if (newGrid[neighbor.y][neighbor.x].numericValue > 9 && flashedThisStep.filter(e => e.x === neighbor.x && e.y === neighbor.y).length === 0 && flashesToResolve.filter(e => e.x === neighbor.x && e.y === neighbor.y).length === 0) { //console.log("DEBUG: adding " + neighbor.x + "," + neighbor.y + " to flashesToResolve"); // add to flashesToResolve flashesToResolve.push(neighbor); } } } } } } // all flashed octopi have their energy reset for (const flashed of flashedThisStep) { newGrid[flashed.y][flashed.x].numericValue = 0; } return { updatedGrid: newGrid.map(e => e.map(f => f.numericValue)), flashedThisStep: flashedThisStep }; } (async function mainExecution() { await openFileForReading('input.txt'); let octopusArr = []; let totalFlashes = 0; for (const line of inputArr) { let tempLine = []; for (const char of line) { tempLine.push(parseInt(char)); } octopusArr.push(tempLine); } //console.log(octopusArr.map(e => e.join('')).join('\n')); console.log("DEBUG: start of step 1: "); console.log(octopusArr.map(e => e.join('')).join('\n')); console.log("DEBUG: totalFlashes = " + totalFlashes); let updatedArr = simulateStep(octopusArr); totalFlashes += updatedArr.flashedThisStep.length; console.log("DEBUG: end of step 1: "); console.log(updatedArr.updatedGrid.map(e => e.join('')).join('\n')); console.log("DEBUG: totalFlashes = " + totalFlashes); let i = 1; while (updatedArr.flashedThisStep.length < (updatedArr.updatedGrid.length * updatedArr.updatedGrid[0].length)) { console.log("DEBUG: start of step " + (i+1) + ": "); console.log(updatedArr.updatedGrid.map(e => e.join('')).join('\n')); console.log("DEBUG: totalFlashes = " + totalFlashes); updatedArr = simulateStep(updatedArr.updatedGrid); totalFlashes += updatedArr.flashedThisStep.length; console.log("DEBUG: end of step " + (i+1) + ": "); console.log(updatedArr.updatedGrid.map(e => e.join('')).join('\n')); console.log("DEBUG: totalFlashes = " + totalFlashes); i++; } console.log("Answer found! They synchronize on step " + i); })();
-
Comment on Day 10: Syntax Scoring in ~comp.advent_of_code
3d12 This one was kind of fun, and the most switch statements I've used so far. I thought for about 10 seconds at the start about building a regex pattern to look for these matches, but then shuddered...This one was kind of fun, and the most switch statements I've used so far. I thought for about 10 seconds at the start about building a regex pattern to look for these matches, but then shuddered and moved on to what I thought would be easier. And, to my great surprise, my code was in a pretty good spot for part 2 using only the most basic array functions!
Part 1
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function analyzeLine(line) { console.log("DEBUG: analyzing line " + line); let stack = []; for (const char of line) { let compare = undefined; switch (char) { case '(': stack.push(char); break; case '[': stack.push(char); break; case '{': stack.push(char); break; case '<': stack.push(char); break; case ')': compare = stack.pop(); if (compare != '(') { return { corrupted: true, violationCharacter: char }; } break; case ']': compare = stack.pop(); if (compare != '[') { return { corrupted: true, violationCharacter: char }; } break; case '}': compare = stack.pop(); if (compare != '{') { return { corrupted: true, violationCharacter: char }; } break; case '>': compare = stack.pop(); if (compare != '<') { return { corrupted: true, violationCharacter: char }; } break; } } return { corrupted: false, violationCharacter: undefined }; } (async function mainExecution() { await openFileForReading('input.txt'); let totalSum = 0; for (const line of inputArr) { let lineResult = analyzeLine(line); console.log(lineResult); if (lineResult.corrupted === true) { let lineScore = 0; console.log(lineResult.violationCharacter); switch (lineResult.violationCharacter) { case ')': lineScore = 3; console.log("DEBUG: ) detected"); break; case ']': lineScore = 57; console.log("DEBUG: ] detected"); break; case '}': lineScore = 1197; console.log("DEBUG: } detected"); break; case '>': lineScore = 25137; console.log("DEBUG: > detected"); break; } console.log("DEBUG: Adding " + lineScore + " to " + totalSum); totalSum += lineScore; } } console.log("Answer found! " + totalSum); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function analyzeLine(line) { console.log("DEBUG: analyzing line " + line); let stack = []; let completionSequence = []; for (const char of line) { let compare = undefined; switch (char) { case '(': stack.push(char); break; case '[': stack.push(char); break; case '{': stack.push(char); break; case '<': stack.push(char); break; case ')': compare = stack.pop(); if (compare != '(') { return { corrupted: true, violationCharacter: char, completionSequence: undefined }; } break; case ']': compare = stack.pop(); if (compare != '[') { return { corrupted: true, violationCharacter: char, completionSequence: undefined }; } break; case '}': compare = stack.pop(); if (compare != '{') { return { corrupted: true, violationCharacter: char, completionSequence: undefined }; } break; case '>': compare = stack.pop(); if (compare != '<') { return { corrupted: true, violationCharacter: char, completionSequence: undefined }; } break; } } if (stack.length > 0) { while (stack.length > 0) { let currentOpening = stack.pop(); switch (currentOpening) { case '(': completionSequence.push(')'); break; case '[': completionSequence.push(']'); break; case '{': completionSequence.push('}'); break; case '<': completionSequence.push('>'); break; } } return { corrupted: false, violationCharacter: undefined, completionSequence: completionSequence }; } else { return { corrupted: false, violationCharacter: undefined, completionSequence: undefined }; } } (async function mainExecution() { await openFileForReading('input.txt'); let lineScores = []; for (const line of inputArr) { let lineResult = analyzeLine(line); console.log(lineResult); if (lineResult.corrupted === false) { let lineScore = 0; for (const char of lineResult.completionSequence) { lineScore *= 5; let charValue = 0; switch (char) { case ')': charValue = 1; break; case ']': charValue = 2; break; case '}': charValue = 3; break; case '>': charValue = 4; break; } lineScore += charValue; } console.log("DEBUG: Line complete! lineScore = " + lineScore); lineScores.push(lineScore); } } console.log(lineScores); console.log("Answer found! " + lineScores.sort((a,b) => { return a - b })[Math.floor((lineScores.length - 1) / 2)]); })();
-
Comment on Day 9: Smoke Basin in ~comp.advent_of_code
3d12 This problem, in my opinion, has a simplistic elegance to it, in that it can be done in many different ways. Recursion, using a fill algorithm, or even just multi-pass scanning. All just a matter...This problem, in my opinion, has a simplistic elegance to it, in that it can be done in many different ways. Recursion, using a fill algorithm, or even just multi-pass scanning. All just a matter of optimization, making this problem accessible to all skill levels of programmer.
Mine was probably not the best solution, but I had a pretty proud moment when I realized that this type of solution would have been pretty much completely out-of-reach for me two years ago.
Part 1
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function isLowPoint(x,y) { let neighbors = []; let rowBoundary = inputArr.length-1; let colBoundary = inputArr[0].length-1; if (x-1 >= 0) { neighbors.push([x-1, y]); } if (x+1 <= colBoundary) { neighbors.push([x+1, y]); } if (y-1 >= 0) { neighbors.push([x, y-1]); } if (y+1 <= rowBoundary) { neighbors.push([x, y+1]); } let myValue = inputArr[y][x]; let isLow = true; for (const neighbor of neighbors) { let theirValue = inputArr[neighbor[1]][neighbor[0]]; if (parseInt(theirValue) <= parseInt(myValue)) { isLow = false; break; } } return isLow; } (async function mainExecution() { await openFileForReading('input.txt'); let totalSum = 0; for (let y = 0; y < inputArr.length; y++) { let currentRow = inputArr[y]; for (let x = 0; x < currentRow.length; x++) { if (isLowPoint(x,y)) { console.log("DEBUG: Found a low point! " + x + "," + y + " -- value: " + currentRow[x]); totalSum += (parseInt(currentRow[x]) + 1); } } } console.log("Answer found! " + totalSum); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function findNeighbors(x,y) { let neighbors = []; let rowBoundary = inputArr.length-1; let colBoundary = inputArr[0].length-1; if (x-1 >= 0) { neighbors.push({ x: x-1, y: y }); } if (x+1 <= colBoundary) { neighbors.push({ x: x+1, y: y }); } if (y-1 >= 0) { neighbors.push({ x: x, y: y-1 }); } if (y+1 <= rowBoundary) { neighbors.push({ x: x, y: y+1 }); } return neighbors; } function isLowPoint(x,y) { let neighbors = findNeighbors(x,y); let myValue = inputArr[y][x]; let isLow = true; for (const neighbor of neighbors) { let theirValue = inputArr[neighbor.y][neighbor.x]; if (parseInt(theirValue) <= parseInt(myValue)) { isLow = false; break; } } return isLow; } function findBasin(startPoint){ let eligibleTiles = [ startPoint ]; let basin = []; while (eligibleTiles.length > 0) { let currentTile = eligibleTiles.pop(); basin.push(currentTile); let currentNeighbors = findNeighbors(currentTile.x,currentTile.y); for (const neighbor of currentNeighbors) { let theirValue = parseInt(inputArr[neighbor.y][neighbor.x]); if (basin.filter(e => (e.x === neighbor.x && e.y === neighbor.y)).length === 0 && eligibleTiles.filter(e => (e.x === neighbor.x && e.y === neighbor.y)).length === 0 && !(theirValue === 9)) { eligibleTiles.push(neighbor); } } } console.log("DEBUG: returning basin = " + basin.map(e => e.x + "," + e.y).join(';')); return basin; } (async function mainExecution() { await openFileForReading('input.txt'); let lowPoints = []; let basins = []; for (let y = 0; y < inputArr.length; y++) { let currentRow = inputArr[y]; for (let x = 0; x < currentRow.length; x++) { if (isLowPoint(x,y)) { console.log("DEBUG: Found a low point! " + x + "," + y + " -- value: " + currentRow[x]); lowPoints.push({ x: x, y: y }); } } } for (const lowPoint of lowPoints) { basins.push(findBasin(lowPoint)); } console.log(basins.map(e => e.length).sort((a,b) => { return b - a })); console.log("Answer found! " + basins.map(e => e.length).sort((a,b) => { return b - a }).slice(0,3).reduce((a,b) => a * b)); })();
-
Comment on Day 8: Seven Segment Search in ~comp.advent_of_code
3d12 I'm so glad to see I'm not the only one who struggled through this one. I went through three different "mental models" of what the final code would look like, and at one point modeled out a...I'm so glad to see I'm not the only one who struggled through this one. I went through three different "mental models" of what the final code would look like, and at one point modeled out a SevenSegmentDisplay and SevenSegmentConsole object, and started implementing wire to display connections for each display to figure out what number it was... Before I realized that none of these numbers can figure it out themselves, they all need the information from each other to tell which number is which!
My solution to part 2 is definitely not optimized, but I don't see anyone else using my same logic! I just implemented the exact steps I took as I was puzzling out the example on paper, with comments to keep my thoughts straight :)
Part 1
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function parseNumbers(line) { let regex = /(\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) \| (\w+) (\w+) (\w+) (\w+)/; let found = line.match(regex); let signalPatterns = []; let outputValues = []; for (let i=1; i<11; i++) { signalPatterns.push(found[i]); } for (let i=11; i<15; i++) { outputValues.push(found[i]); } return { signalPatterns: signalPatterns, outputValues: outputValues }; } (async function mainExecution() { await openFileForReading('input.txt'); let totalAppearances = 0; for (const line of inputArr) { let parsed = parseNumbers(line); totalAppearances += parsed.outputValues.filter(e => e.length === 2 || e.length === 4 || e.length === 3 || e.length === 7).length } console.log("Answer found! " + totalAppearances); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function parseNumbers(line) { let regex = /(\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) (\w+) \| (\w+) (\w+) (\w+) (\w+)/; let found = line.match(regex); let signalPatterns = []; let outputValues = []; for (let i=1; i<11; i++) { signalPatterns.push(found[i]); } for (let i=11; i<15; i++) { outputValues.push(found[i]); } return { signalPatterns: signalPatterns, outputValues: outputValues }; } class SignalPatternConsole { displays = []; constructor(signalPatterns) { // store signal patterns for (const pattern of signalPatterns) { this.displays.push({ wires: pattern, numericValue: undefined }) } // compute // step 1: identify 1, 4, 7, and 8 for (let display of this.displays) { if (display.wires.length === 2) { display.numericValue = 1; } if (display.wires.length === 3) { display.numericValue = 7; } if (display.wires.length === 4) { display.numericValue = 4; } if (display.wires.length === 7) { display.numericValue = 8; } } // step 2: identify the top segment let one = this.displays.filter(e => e.numericValue === 1)[0]; let seven = this.displays.filter(e => e.numericValue === 7)[0]; let topSegment = 'x'; for (const segment of seven.wires) { if (!one.wires.includes(segment)) { topSegment = segment; } } // step 3: determine which is zero based on the middle (found from // the difference between 4 and 1) let four = this.displays.filter(e => e.numericValue === 4)[0]; let middleSegment = 'x'; let possibleMiddle = []; for (const segment of four.wires) { if (!one.wires.includes(segment)) { possibleMiddle.push(segment); } } let sixSegmentClub = this.displays.filter(e => e.wires.length === 6); for (let member of sixSegmentClub) { for (const possibility of possibleMiddle) { if (!member.wires.includes(possibility)){ member.numericValue = 0; } } } let zero = this.displays.filter(e => e.numericValue === 0)[0]; // step 4: determining six based on missing one value from four sixSegmentClub = this.displays.filter(e => e.numericValue === undefined && e.wires.length === 6); for (let member of sixSegmentClub) { let matches = 0; for (const wire of four.wires) { if (member.wires.includes(wire)) { matches++; } } if (matches === 3) { member.numericValue = 6; } } let six = this.displays.filter(e => e.numericValue === 6)[0]; // step 5: (freebie) nine is the last six-segment number let nine = this.displays.filter(e => e.numericValue === undefined && e.wires.length === 6)[0]; nine.numericValue = 9; // step 6: match 2 based on only having 2 segments from 4 let fiveSegmentClub = this.displays.filter(e => e.numericValue === undefined && e.wires.length === 5); for (let member of fiveSegmentClub) { let matches = 0; for (const wire of four.wires) { if (member.wires.includes(wire)) { matches++; } } if (matches === 2) { member.numericValue = 2; } } let two = this.displays.filter(e => e.numericValue === 2)[0]; // step 7: match 5 based on only having one segment from 1 fiveSegmentClub = this.displays.filter(e => e.numericValue === undefined && e.wires.length === 5); for (let member of fiveSegmentClub) { let matches = 0; for (const wire of one.wires) { if (member.wires.includes(wire)) { matches++; } } if (matches === 1) { member.numericValue = 5; } } let five = this.displays.filter(e => e.numericValue === 5)[0]; // step 8: last unassigned value is 3 let three = this.displays.filter(e => e.numericValue === undefined)[0]; three.numericValue = 3; } translationArray() { let toReturn = []; for (const display of this.displays) { toReturn.push({ wires: display.wires, numericValue: display.numericValue }); } return toReturn; } } (async function mainExecution() { await openFileForReading('input.txt'); let totalSum = 0; for (const line of inputArr) { let parsed = parseNumbers(line); let cons = new SignalPatternConsole(parsed.signalPatterns); let translation = cons.translationArray(); let values = parsed.outputValues; let currentNumber = []; for (const value of values) { let searchList = translation.filter(e => (e.wires.length === value.length)); for (const wire of value) { searchList = searchList.filter(e => (e.wires.includes(wire))); if (searchList.length === 1) { currentNumber.push(searchList[0].numericValue); break; } } } console.log("DEBUG: Adding " + parseInt(currentNumber.join('')) + " to " + totalSum); totalSum += parseInt(currentNumber.join('')); } console.log("Answer found! " + totalSum); })();
-
Comment on Day 7: The Treachery of Whales in ~comp.advent_of_code
3d12 (edited )LinkHello, I'm back! Took a couple days away, solving problems without posting. This one was a good example of a problem where a little math knowledge can go a long way for optimization. Using...Hello, I'm back! Took a couple days away, solving problems without posting.
This one was a good example of a problem where a little math knowledge can go a long way for optimization. Using absolute value instead of writing a loop to "step" each crab into place optimizes by a factor of O(n) -- a good lesson for beginning programmers :)
Part 1
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } (async function mainExecution() { await openFileForReading('input.txt'); let currentFuel = 0; let bestFuel = 99999999; let bestIndex = 0; let crabPositionArr = inputArr[0].split(','); let maxIndex = crabPositionArr.reduce((a,b) => { return Math.max(a,b) }); for (let i = 0; i<maxIndex; i++) { currentFuel = 0; // try aligning all the crabs to this index for (crab of crabPositionArr) { currentFuel += Math.abs(crab - i); } // if this uses less fuel than bestFuel, save this index to bestIndex if (currentFuel < bestFuel) { bestFuel = currentFuel; bestIndex = i; } } console.log("Answer found! Index " + bestIndex + " uses the least fuel at " + bestFuel); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function crabFuel(spaces) { let totalFuel = 0; for (let i = spaces; i > 0; i--) { totalFuel += i; } return totalFuel; } (async function mainExecution() { await openFileForReading('input.txt'); let currentFuel = 0; let bestFuel = 99999999; let bestIndex = 0; let crabPositionArr = inputArr[0].split(','); let maxIndex = crabPositionArr.reduce((a,b) => { return Math.max(a,b) }); for (let i = 0; i<maxIndex; i++) { currentFuel = 0; // try aligning all the crabs to this index for (crab of crabPositionArr) { currentFuel += crabFuel(Math.abs(crab - i)); } // if this uses less fuel than bestFuel, save this index to bestIndex if (currentFuel < bestFuel) { bestFuel = currentFuel; bestIndex = i; } } console.log("Answer found! Index " + bestIndex + " uses the least fuel at " + bestFuel); })();
-
Comment on Day 6: Lanternfish in ~comp.advent_of_code
3d12 I knew something was up with the way the problem was described, but to be honest, I was expecting a change in the reproduction mechanism instead of what we got. The part 2 twist seemed almost too...I knew something was up with the way the problem was described, but to be honest, I was expecting a change in the reproduction mechanism instead of what we got. The part 2 twist seemed almost too simple until I saw my code struggling to run the test data and eventually getting an "invalid size error" trying to fit 169 million values into an array. Definitely an interesting mislead. I feel pity for anyone who tried to model part 1 using objects.
Part 1
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function processDay(inputArray) { let fishToBeBorn = 0; let outputArray = []; for (const fish of inputArray) { if (fish === 0) { fishToBeBorn++; outputArray.push(6); } else { outputArray.push(fish - 1); } } for (let i=0; i<fishToBeBorn; i++) { outputArray.push(8); } return outputArray; } (async function mainExecution() { await openFileForReading('input.txt'); let lanternFishArray = inputArr[0].split(',').map(e => parseInt(e)); let days = 0; let totalFish = 0; while (true) { lanternFishArray = processDay(lanternFishArray); days++; if (days === 80) { totalFish = lanternFishArray.length; break; } } console.log("Answer found! " + totalFish); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function processDay(inputSerializedArray) { let fishToBeBorn = 0; let outputObject = { zero: 0, one: 0, two: 0, three: 0, four: 0, five: 0, six: 0, seven: 0, eight: 0 }; if (inputSerializedArray.zero > 0) { fishToBeBorn = inputSerializedArray.zero; } outputObject.zero = inputSerializedArray.one; outputObject.one = inputSerializedArray.two; outputObject.two = inputSerializedArray.three; outputObject.three = inputSerializedArray.four; outputObject.four = inputSerializedArray.five; outputObject.five = inputSerializedArray.six; outputObject.six = (inputSerializedArray.seven + fishToBeBorn); outputObject.seven = inputSerializedArray.eight; outputObject.eight = fishToBeBorn; return outputObject; } function serializeArray(inputArray) { let returnObject = { zero: 0, one: 0, two: 0, three: 0, four: 0, five: 0, six: 0, seven: 0, eight: 0 }; for (const item of inputArray) { switch (item) { case 0: returnObject.zero++; break; case 1: returnObject.one++; break; case 2: returnObject.two++; break; case 3: returnObject.three++; break; case 4: returnObject.four++; break; case 5: returnObject.five++; break; case 6: returnObject.six++; break; case 7: returnObject.seven++; break; case 8: returnObject.eight++; break; default: return new Error("Invalid number in serialization: " + item); } } return returnObject; } (async function mainExecution() { await openFileForReading('input.txt'); let lanternFishArray = serializeArray(inputArr[0].split(',').map(e => parseInt(e))); console.log(lanternFishArray); let days = 0; let totalFish = 0; while (true) { console.log("DEBUG: Processing day " + (days+1) + "..."); lanternFishArray = processDay(lanternFishArray); days++; if (days === 256) { totalFish = (lanternFishArray.zero + lanternFishArray.one + lanternFishArray.two + lanternFishArray.three + lanternFishArray.four + lanternFishArray.five + lanternFishArray.six + lanternFishArray.seven + lanternFishArray.eight); break; } } console.log("Answer found! " + totalFish); })();
-
Comment on Day 5: Hydrothermal Venture in ~comp.advent_of_code
3d12 Wow, I was definitely expecting fewer people saying part 2 was difficult. The diff between my part 1 and part 2 is literally 2 lines, I just removed the validation check I put on the input step....Wow, I was definitely expecting fewer people saying part 2 was difficult. The diff between my part 1 and part 2 is literally 2 lines, I just removed the validation check I put on the input step. Though to be fair, I suspected the twist right away when the puzzle said to ignore certain inputs... ;)
Part 1
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function findMaxDimensions(vectorArray) { let maxX = 0; let maxY = 0; for (const vectorPair of vectorArray) { if (vectorPair.x1 > maxX) { maxX = vectorPair.x1; } if (vectorPair.y1 > maxY) { maxY = vectorPair.y1; } if (vectorPair.x2 > maxX) { maxX = vectorPair.x2; } if (vectorPair.y2 > maxY) { maxY = vectorPair.y2; } } return { maxX: maxX, maxY: maxY }; } function initGrid(x, y) { let grid = []; for (let i=0; i<=y; i++) { let currentRow = []; for (let j=0; j<=x; j++) { currentRow.push('.'); } grid.push(currentRow); } return grid; } function addLine(grid, vector) { let startX = vector.x1; let startY = vector.y1; let endX = vector.x2; let endY = vector.y2; let cursorX = startX; let cursorY = startY; console.log("DEBUG: startX = " + startX + ", startY = " + startY); console.log("DEBUG: endX = " + endX + ", endY = " + endY); console.log("DEBUG: cursorX != endX is " + (cursorX != endX)); console.log("DEBUG: cursorY != endY is " + (cursorY != endY)); while (true) { console.log("DEBUG: cursorX = " + cursorX + ", cursorY = " + cursorY); let row = grid[cursorY]; let currentValue = row[cursorX]; if (currentValue === '.') { grid[cursorY][cursorX] = 1; } else { grid[cursorY][cursorX]++; } if (cursorX === endX && cursorY === endY) { break; } console.log("DEBUG: cursorX != endX is " + (cursorX != endX)); if (cursorX != endX && cursorX > endX) { cursorX--; } else if (cursorX != endX && cursorX < endX) { cursorX++; } console.log("DEBUG: cursorY != endY is " + (cursorY != endY)); if (cursorY != endY && cursorY > endY) { cursorY--; } else if (cursorY != endY && cursorY < endY) { cursorY++; } } } function getPoints(grid) { let points = 0; for (const row of grid) { for (const value of row) { if (value > 1) { points++; } } } return points; } function isDiagonal(vector) { return ((vector.x1 != vector.x2) && (vector.y1 != vector.y2)); } (async function mainExecution() { await openFileForReading('input.txt'); let vectorArray = inputArr.map(e => { let regex = /(\d+),(\d+) -> (\d+),(\d+)/; let found = e.match(regex); return { x1: parseInt(found[1]), y1: parseInt(found[2]), x2: parseInt(found[3]), y2: parseInt(found[4]) }; }); gridDimensions = findMaxDimensions(vectorArray); let grid = initGrid(gridDimensions.maxX, gridDimensions.maxY); console.log(grid.map(e => e.join('')).join('\n')); for (const vector of vectorArray) { if (!isDiagonal(vector)) { console.log("DEBUG: Operating on vector " + vector.x1 + "," + vector.y1 + " -> " + vector.x2 + "," + vector.y2); addLine(grid, vector); console.log(grid.map(e => e.join('')).join('\n')); } } console.log("Answer found! " + getPoints(grid)); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function findMaxDimensions(vectorArray) { let maxX = 0; let maxY = 0; for (const vectorPair of vectorArray) { if (vectorPair.x1 > maxX) { maxX = vectorPair.x1; } if (vectorPair.y1 > maxY) { maxY = vectorPair.y1; } if (vectorPair.x2 > maxX) { maxX = vectorPair.x2; } if (vectorPair.y2 > maxY) { maxY = vectorPair.y2; } } return { maxX: maxX, maxY: maxY }; } function initGrid(x, y) { let grid = []; for (let i=0; i<=y; i++) { let currentRow = []; for (let j=0; j<=x; j++) { currentRow.push('.'); } grid.push(currentRow); } return grid; } function addLine(grid, vector) { let startX = vector.x1; let startY = vector.y1; let endX = vector.x2; let endY = vector.y2; let cursorX = startX; let cursorY = startY; console.log("DEBUG: startX = " + startX + ", startY = " + startY); console.log("DEBUG: endX = " + endX + ", endY = " + endY); console.log("DEBUG: cursorX != endX is " + (cursorX != endX)); console.log("DEBUG: cursorY != endY is " + (cursorY != endY)); while (true) { console.log("DEBUG: cursorX = " + cursorX + ", cursorY = " + cursorY); let row = grid[cursorY]; let currentValue = row[cursorX]; if (currentValue === '.') { grid[cursorY][cursorX] = 1; } else { grid[cursorY][cursorX]++; } if (cursorX === endX && cursorY === endY) { break; } console.log("DEBUG: cursorX != endX is " + (cursorX != endX)); if (cursorX != endX && cursorX > endX) { cursorX--; } else if (cursorX != endX && cursorX < endX) { cursorX++; } console.log("DEBUG: cursorY != endY is " + (cursorY != endY)); if (cursorY != endY && cursorY > endY) { cursorY--; } else if (cursorY != endY && cursorY < endY) { cursorY++; } } } function getPoints(grid) { let points = 0; for (const row of grid) { for (const value of row) { if (value > 1) { points++; } } } return points; } function isDiagonal(vector) { return ((vector.x1 != vector.x2) && (vector.y1 != vector.y2)); } (async function mainExecution() { await openFileForReading('input.txt'); let vectorArray = inputArr.map(e => { let regex = /(\d+),(\d+) -> (\d+),(\d+)/; let found = e.match(regex); return { x1: parseInt(found[1]), y1: parseInt(found[2]), x2: parseInt(found[3]), y2: parseInt(found[4]) }; }); gridDimensions = findMaxDimensions(vectorArray); let grid = initGrid(gridDimensions.maxX, gridDimensions.maxY); console.log(grid.map(e => e.join('')).join('\n')); for (const vector of vectorArray) { console.log("DEBUG: Operating on vector " + vector.x1 + "," + vector.y1 + " -> " + vector.x2 + "," + vector.y2); addLine(grid, vector); console.log(grid.map(e => e.join('')).join('\n')); } console.log("Answer found! " + getPoints(grid)); })();
-
Comment on How a NYTimes reporter, Ian Urbina, collects royalties from hundreds of musicians via the Outlaw Ocean Music Project in ~music
3d12 Thanks for linking this, cfabbro. For anyone who's not familiar, Benn Jordan makes amazing electronic music under the name The Flashbulb, and his channel is packed full of awesome gear reviews and...Thanks for linking this, cfabbro. For anyone who's not familiar, Benn Jordan makes amazing electronic music under the name The Flashbulb, and his channel is packed full of awesome gear reviews and informational videos. Would highly recommend checking him out if you enjoyed this video.
-
Comment on Day 4: Giant Squid in ~comp.advent_of_code
3d12 Compared to day 3, this one was easier and actually kind of fun to implement. I was quite happy with the change from part 1 to part 2. I was expecting a different twist, so my implementation only...Compared to day 3, this one was easier and actually kind of fun to implement. I was quite happy with the change from part 1 to part 2. I was expecting a different twist, so my implementation only required minimal changes to get the new answer.
Part 1
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function parseBingoCard(bingoCardText) { let bingoCardArray = []; let rows = bingoCardText.split('\n'); for (const row of rows) { let regex = /(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/; let found = row.match(regex); let rowArray = [found[1],found[2],found[3],found[4],found[5]]; bingoCardArray.push(rowArray); } return bingoCardArray; } function splitBingoCards() { let splitArray = []; let currentBingoCardArray = []; // skip the first two lines, bingo cards start on line 3 let bingoCardArray = inputArr.slice(2); for (const line of bingoCardArray) { // on blank line, reset accumulated line and send for parsing if (line.trim().length === 0) { splitArray.push(parseBingoCard(currentBingoCardArray.join('\n'))); currentBingoCardArray = []; } else { currentBingoCardArray.push(line); } } // flushing the buffer, in case the last line is not newline-terminated if (currentBingoCardArray.length != 0) { splitArray.push(parseBingoCard(currentBingoCardArray.join('\n'))); } return splitArray; } function findBingo(bingoCard, numbersCalled) { // look for horizontal bingos for (const row of bingoCard) { let horizontalBingo = true; for (const number of row) { if (!numbersCalled.includes(parseInt(number))) { horizontalBingo = false; break; } } if (horizontalBingo === true) { return true; } } // look for vertical bingos for (let colIndex = 0; colIndex < bingoCard[0].length; colIndex++) { let verticalBingo = true; for (const row of bingoCard) { if (!numbersCalled.includes(parseInt(row[colIndex]))) { verticalBingo = false; break; } } if (verticalBingo === true) { return true; } } return false; } function findBingoScore(bingoCard, numbersCalled) { let pointSpaces = []; for (const row of bingoCard) { for (const num of row) { if (!numbersCalled.includes(parseInt(num))) { pointSpaces.push(parseInt(num)); } } } return (pointSpaces.reduce((a,b) => a+b) * numbersCalled[numbersCalled.length-1]); } (async function mainExecution() { await openFileForReading('input.txt'); let numbersToCall = inputArr[0].split(',').map(e => parseInt(e)); console.log("DEBUG: numbersToCall = " + numbersToCall); let bingoCardArray = splitBingoCards(); let numberCalledIndex = 0; let numbersCalled = []; let winningBoard = []; while (winningBoard.length === 0) { // call new number numberCalledIndex++; numbersCalled = numbersToCall.slice(0,numberCalledIndex); // check for win for (bingoCard of bingoCardArray) { if (findBingo(bingoCard,numbersCalled)) { winningBoard = bingoCard; break; } } } console.log("DEBUG: winningBoard =\n" + winningBoard.join('\n')); console.log("DEBUG: numbersCalled = " + numbersCalled); console.log("Answer found! " + findBingoScore(winningBoard,numbersCalled)); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let inputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { inputArr.push(line); } catch(e) { console.error(e); } } } function parseBingoCard(bingoCardText) { let bingoCardArray = []; let rows = bingoCardText.split('\n'); for (const row of rows) { let regex = /(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/; let found = row.match(regex); let rowArray = [found[1],found[2],found[3],found[4],found[5]]; bingoCardArray.push(rowArray); } return bingoCardArray; } function splitBingoCards() { let splitArray = []; let currentBingoCardArray = []; // skip the first two lines, bingo cards start on line 3 let bingoCardArray = inputArr.slice(2); for (const line of bingoCardArray) { // on blank line, reset accumulated line and send for parsing if (line.trim().length === 0) { splitArray.push(parseBingoCard(currentBingoCardArray.join('\n'))); currentBingoCardArray = []; } else { currentBingoCardArray.push(line); } } // flushing the buffer, in case the last line is not newline-terminated if (currentBingoCardArray.length != 0) { splitArray.push(parseBingoCard(currentBingoCardArray.join('\n'))); } return splitArray; } function findBingo(bingoCard, numbersCalled) { // look for horizontal bingos for (const row of bingoCard) { let horizontalBingo = true; for (const number of row) { if (!numbersCalled.includes(parseInt(number))) { horizontalBingo = false; break; } } if (horizontalBingo === true) { return true; } } // look for vertical bingos for (let colIndex = 0; colIndex < bingoCard[0].length; colIndex++) { let verticalBingo = true; for (const row of bingoCard) { if (!numbersCalled.includes(parseInt(row[colIndex]))) { verticalBingo = false; break; } } if (verticalBingo === true) { return true; } } return false; } function findBingoScore(bingoCard, numbersCalled) { let pointSpaces = []; for (const row of bingoCard) { for (const num of row) { if (!numbersCalled.includes(parseInt(num))) { pointSpaces.push(parseInt(num)); } } } return (pointSpaces.reduce((a,b) => a+b) * numbersCalled[numbersCalled.length-1]); } (async function mainExecution() { await openFileForReading('input.txt'); let numbersToCall = inputArr[0].split(',').map(e => parseInt(e)); console.log("DEBUG: numbersToCall = " + numbersToCall); let bingoCardArray = splitBingoCards(); let numberCalledIndex = 0; let numbersCalled = []; let winningBoards = []; while (winningBoards.length < bingoCardArray.length) { // call new number numberCalledIndex++; numbersCalled = numbersToCall.slice(0,numberCalledIndex); // check for wins for (let i=0; i<bingoCardArray.length; i++) { if (!winningBoards.includes(i)) { if (findBingo(bingoCardArray[i], numbersCalled)) { winningBoards.push(i); } } } } console.log("DEBUG: last winningBoard =\n" + bingoCardArray[winningBoards[winningBoards.length-1]].join('\n')); console.log("DEBUG: numbersCalled = " + numbersCalled); console.log("Answer found! " + findBingoScore(bingoCardArray[winningBoards[winningBoards.length-1]],numbersCalled)); })();
-
Comment on Day 3: Binary Diagnostic in ~comp.advent_of_code
3d12 Haha, this one absolutely killed me. While I defeated my own purpose here in my haste to get caught up on the problems I was behind on, I did manage to get a functional solution regardless of its...Haha, this one absolutely killed me. While I defeated my own purpose here in my haste to get caught up on the problems I was behind on, I did manage to get a functional solution regardless of its readability. I've already promised myself no more of this sloppy type of implementation, since my goal here is to get familiar with the more convenient parts of Node/JS and not just implement everything with indices and for loops. :)
Part 1
const fs = require('fs'); const readline = require('readline'); let binaryInputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { //directionArr.push(parseInt(line)); binaryInputArr.push(line); } catch(e) { console.error(e); } } } (async function mainExecution() { await openFileForReading('input.txt'); let positionalCounts = []; const lengthCheckString = binaryInputArr[0]; for (let i=0; i<lengthCheckString.length; i++) { positionalCounts.push({ zeroes: 0, ones: 0 }); } for (const binaryInput of binaryInputArr) { for (let i=0; i<binaryInput.length; i++) { if (binaryInput[i] === '0') { positionalCounts[i].zeroes++; } else if (binaryInput[i] === '1') { positionalCounts[i].ones++; } } } let gammaRate = []; let epsilonRate = []; for (let i=0; i<positionalCounts.length; i++) { if (positionalCounts[i].zeroes > positionalCounts[i].ones) { gammaRate.push('0'); epsilonRate.push('1'); } else if (positionalCounts[i].ones > positionalCounts[i].zeroes) { gammaRate.push('1'); epsilonRate.push('0'); } } let gammaRateString = gammaRate.join(''); let gammaRateInt = parseInt(gammaRateString, 2); let epsilonRateString = epsilonRate.join(''); let epsilonRateInt = parseInt(epsilonRateString, 2); console.log("Answer found! " + (gammaRateInt * epsilonRateInt)); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let binaryInputArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { //directionArr.push(parseInt(line)); binaryInputArr.push(line); } catch(e) { console.error(e); } } } (async function mainExecution() { await openFileForReading('input.txt'); let oxygenGenRating = ''; let filteredArray = binaryInputArr; let positionalCounts = []; let binaryInputIndex = 0; while (oxygenGenRating === '') { if (filteredArray.length === 1) { oxygenGenRating = filteredArray[0]; break; } const lengthCheckString = filteredArray[0]; positionalCounts = []; for (let i=0; i<lengthCheckString.length; i++) { positionalCounts.push({ zeroes: 0, ones: 0 }); } for (let i=0; i<filteredArray.length; i++) { let currentString = filteredArray[i]; for (let j=0; j<positionalCounts.length; j++) { if (currentString[j] === '0') { positionalCounts[j].zeroes++; } else if (currentString[j] === '1') { positionalCounts[j].ones++; } } } let filterChoice = ''; if (positionalCounts[binaryInputIndex].zeroes > positionalCounts[binaryInputIndex].ones) { filterChoice = '0'; } else if (positionalCounts[binaryInputIndex].ones >= positionalCounts[binaryInputIndex].zeroes) { filterChoice = '1'; } filteredArray = filteredArray.filter(binaryNumber => binaryNumber[binaryInputIndex] === filterChoice); binaryInputIndex++; } let co2ScrubRating = ''; let filteredArray2 = binaryInputArr; positionalCounts = []; binaryInputIndex = 0; while (co2ScrubRating === '') { if (filteredArray2.length === 1) { co2ScrubRating = filteredArray2[0]; break; } const lengthCheckString = filteredArray2[0]; positionalCounts = []; for (let i=0; i<lengthCheckString.length; i++) { positionalCounts.push({ zeroes: 0, ones: 0 }); } for (let i=0; i<filteredArray2.length; i++) { let currentString = filteredArray2[i]; for (let j=0; j<positionalCounts.length; j++) { if (currentString[j] === '0') { positionalCounts[j].zeroes++; } else if (currentString[j] === '1') { positionalCounts[j].ones++; } } } let filterChoice = ''; if (positionalCounts[binaryInputIndex].zeroes <= positionalCounts[binaryInputIndex].ones) { filterChoice = '0'; } else if (positionalCounts[binaryInputIndex].ones < positionalCounts[binaryInputIndex].zeroes) { filterChoice = '1'; } filteredArray2 = filteredArray2.filter(binaryNumber => binaryNumber[binaryInputIndex] === filterChoice); binaryInputIndex++; } let oxygenGenRatingDecimal = parseInt(oxygenGenRating,2); let co2ScrubRatingDecimal = parseInt(co2ScrubRating,2); console.log("Answer found! \nOxygen Generator Rating: " + oxygenGenRatingDecimal + "\nCO2 Scrubber Rating: " + co2ScrubRatingDecimal + "\n" + oxygenGenRatingDecimal + " * " + co2ScrubRatingDecimal + " = " + (oxygenGenRatingDecimal * co2ScrubRatingDecimal)); })();
-
Comment on Day 2: Dive! in ~comp.advent_of_code
3d12 I agree with everyone else, this one felt a little easy. Still, no compaints, I'm sure it will get more difficult quite quickly! Part 1 const fs = require('fs'); const readline =...I agree with everyone else, this one felt a little easy. Still, no compaints, I'm sure it will get more difficult quite quickly!
Part 1
const fs = require('fs'); const readline = require('readline'); let directionArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { //directionArr.push(parseInt(line)); directionArr.push(line); } catch(e) { console.error(e); } } } function interpretDirection(inputDirection) { let hmodifier = 0; let vmodifier = 0; const regex = /(\w+) (\d+)/; const found = inputDirection.match(regex); const direction = found[1]; const distance = parseInt(found[2]); switch (direction) { case 'forward': hmodifier += distance; break; case 'down': vmodifier += distance; break; case 'up': vmodifier -= distance break; } return { hmodifier: hmodifier, vmodifier: vmodifier }; } (async function mainExecution() { await openFileForReading('input.txt'); let hposition = 0; let vposition = 0; for (const direction of directionArr) { let outcome = interpretDirection(direction); console.log("hmodifier: " + outcome.hmodifier + ", vmodifier: " + outcome.vmodifier) hposition += outcome.hmodifier; if (vposition + outcome.vmodifier < 0) { vposition = 0; } else { vposition += outcome.vmodifier; } console.log("Current position: " + hposition + "," + vposition); } console.log("Answer found! " + (hposition * vposition)); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let directionArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { //directionArr.push(parseInt(line)); directionArr.push(line); } catch(e) { console.error(e); } } } function interpretDirection(inputDirection) { let command = 'null'; let value = 0; const regex = /(\w+) (\d+)/; const found = inputDirection.match(regex); command = found[1]; value = parseInt(found[2]); return { command: command, value: value }; } (async function mainExecution() { await openFileForReading('input.txt'); let hposition = 0; let vposition = 0; let aim = 0; for (const direction of directionArr) { let outcome = interpretDirection(direction); console.log("command: " + outcome.command + ", value: " + outcome.value) switch (outcome.command) { case 'up': if (aim - outcome.value < 0) { aim = 0; } else { aim -= outcome.value; } break; case 'down': aim += outcome.value; break; case 'forward': hposition += outcome.value; vposition += (aim * outcome.value); break; } } console.log("Answer found! " + (hposition * vposition)); })();
-
Comment on Day 1: Sonar Sweep in ~comp.advent_of_code
3d12 Late entry, just catching up this weekend! I'll be doing this in Javascript (Node) this year again, since I'm getting better at using the language, and would like to potentially start using it...Late entry, just catching up this weekend! I'll be doing this in Javascript (Node) this year again, since I'm getting better at using the language, and would like to potentially start using it professionally in 2022.
Repo is here
Part 1
const fs = require('fs'); const readline = require('readline'); let depthArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { depthArr.push(parseInt(line)); } catch(e) { console.error(e); } } } (async function mainExecution() { await openFileForReading('input.txt'); let currentDepth = 0; let firstDepth = true; let numIncreases = 0; for (const depth of depthArr) { if (firstDepth != true) { diff = depth - currentDepth; if (diff > 0) { console.log("Depth increased from " + currentDepth + " to " + depth); numIncreases++; } } currentDepth = depth; firstDepth = false; } console.log("Answer found! " + numIncreases); })();
Part 2
const fs = require('fs'); const readline = require('readline'); let depthArr = []; async function openFileForReading(file) { const fileStream = fs.createReadStream(file); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity }); for await (const line of rl) { try { depthArr.push(parseInt(line)); } catch(e) { console.error(e); } } } (async function mainExecution() { await openFileForReading('input.txt'); let currentDepth = 0; let currentWindowIndex = 0; let firstDepth = true; let numIncreases = 0; for (let currentWindowIndex = 0; currentWindowIndex < depthArr.length-2; currentWindowIndex++) { if (firstDepth != true) { depthSum = depthArr[currentWindowIndex] + depthArr[currentWindowIndex+1] + depthArr[currentWindowIndex+2]; diff = depthSum - currentDepth; if (diff > 0) { console.log("Depth increased from " + currentDepth + " to " + depthSum); numIncreases++; } } currentDepth = depthArr[currentWindowIndex] + depthArr[currentWindowIndex+1] + depthArr[currentWindowIndex+2]; firstDepth = false; } console.log("Answer found! " + numIncreases); })();
Paramount+ with Showtime: Deluxe Ultimate Complete Streaming Service of the Year Edition