diff --git a/2023/Day_17/README.md b/2023/Day_17/README.md index eb71403..72819bd 100644 --- a/2023/Day_17/README.md +++ b/2023/Day_17/README.md @@ -59,3 +59,57 @@ One way to **minimize heat loss** is this path: This path never moves more than three consecutive blocks in the same direction and incurs a heat loss of only **`102`**. Directing the crucible from the lava pool to the machine parts factory, but not moving more than three consecutive blocks in the same direction, **what is the least heat loss it can incur?** + +--- + +## --- Part Two --- + +The crucibles of lava simply aren't large enough to provide an adequate supply of lava to the machine parts factory. Instead, the Elves are going to upgrade to **ultra crucibles**. + +Ultra crucibles are even more difficult to steer than normal crucibles. Not only do they have trouble going in a straight line, but they also have trouble turning! + +Once an ultra crucible starts moving in a direction, it needs to move **a minimum of four blocks** in that direction before it can turn (or even before it can stop at the end). However, it will eventually start to get wobbly: an ultra crucible can move a maximum of **ten consecutive blocks** without turning. + +In the above example, an ultra crucible could follow this path to minimize heat loss: + +``` +2>>>>>>>>1323 +32154535v5623 +32552456v4254 +34465858v5452 +45466578v>>>> +143859879845v +445787698776v +363787797965v +465496798688v +456467998645v +122468686556v +254654888773v +432267465553v +``` + +In the above example, an ultra crucible would incur the minimum possible heat loss of **`94`**. + +Here's another example: + +``` +111111111111 +999999999991 +999999999991 +999999999991 +999999999991 +``` + +Sadly, an ultra crucible would need to take an unfortunate path like this one: + +``` +1>>>>>>>1111 +9999999v9991 +9999999v9991 +9999999v9991 +9999999v>>>> +``` + +This route causes the ultra crucible to incur the minimum possible heat loss of **`71`**. + +Directing the **ultra crucible** from the lava pool to the machine parts factory, **what is the least heat loss it can incur?** diff --git a/2023/Day_17/part_1.js b/2023/Day_17/part_1.js index ec7e0ae..5b8485b 100644 --- a/2023/Day_17/part_1.js +++ b/2023/Day_17/part_1.js @@ -1,19 +1,36 @@ "use strict"; +/* eslint-disable one-var */ + const fs = require("node:fs"); const path = require("node:path"); const { performance } = require("node:perf_hooks"); -const INPUT = String(fs.readFileSync(path.join(__dirname, "input.txt"))).trim().split("\n"); +const INPUT = String(fs.readFileSync(path.join(__dirname, "input.txt"))).trim().split("\n").map(l => l.split("").map(Number)); const pStart = performance.now(); -// -// YOUR CODE HERE -// -const result = "..."; +let res = 0; +const q = [{ c: 0, row: 0, col: 0, dR: 0, dC: 0, m: 0 }], seen = new Set(); +while (q.length){ // @ts-ignore + const { c, row, col, dR, dC, m } = q.sort((p, n) => n.c - p.c).pop(); + (row === (INPUT.length - 1) && col === (INPUT[0].length - 1) && m >= 1) && (res = c); + if (res !== 0) break; + + if (seen.has(JSON.stringify([row, col, dR, dC, m]))) continue; + seen.add(JSON.stringify([row, col, dR, dC, m])); + + ((m < 3 && !(dR === 0 && dC === 0)) + && (row + dR >= 0 && row + dR < INPUT.length && col + dC >= 0 && col + dC < INPUT[0].length) + && q.push( { c: c + INPUT[row + dR][col + dC], row: row + dR, col: col + dC, dR, dC, m: m + 1 }) || 1) + && ((m >= 1 || (dR === 0 && dC === 0)) && [[0, 1], [1, 0], [0, -1], [-1, 0]].forEach(([nDR, nDC]) => ( + (JSON.stringify([nDR, nDC]) !== JSON.stringify([dR, dC])) && (JSON.stringify([nDR, nDC]) !== JSON.stringify([-dR, -dC]))) + && (row + nDR >= 0 && row + nDR < INPUT.length && col + nDC >= 0 && col + nDC < INPUT[0].length) + && q.push({ c: c + INPUT[row + nDR][col + nDC], row: row + nDR, col: col + nDC, dR: nDR, dC: nDC, m: 1 }), + )); +} const pEnd = performance.now(); -console.log(": " + result); +console.log("LEAST HEAT LOSS: " + res); console.log(pEnd - pStart); diff --git a/2023/Day_17/part_2.js b/2023/Day_17/part_2.js index ec7e0ae..02000bf 100644 --- a/2023/Day_17/part_2.js +++ b/2023/Day_17/part_2.js @@ -1,19 +1,36 @@ "use strict"; +/* eslint-disable one-var */ + const fs = require("node:fs"); const path = require("node:path"); const { performance } = require("node:perf_hooks"); -const INPUT = String(fs.readFileSync(path.join(__dirname, "input.txt"))).trim().split("\n"); +const INPUT = String(fs.readFileSync(path.join(__dirname, "input.txt"))).trim().split("\n").map(l => l.split("").map(Number)); const pStart = performance.now(); -// -// YOUR CODE HERE -// -const result = "..."; +let res = 0; +const q = [{ c: 0, row: 0, col: 0, dR: 0, dC: 0, m: 0 }], seen = new Set(); +while (q.length){ // @ts-ignore + const { c, row, col, dR, dC, m } = q.sort((p, n) => n.c - p.c).pop(); + (row === (INPUT.length - 1) && col === (INPUT[0].length - 1) && m >= 4) && (res = c); + if (res !== 0) break; + + if (seen.has(JSON.stringify([row, col, dR, dC, m]))) continue; + seen.add(JSON.stringify([row, col, dR, dC, m])); + + ((m < 10 && !(dR === 0 && dC === 0)) + && (row + dR >= 0 && row + dR < INPUT.length && col + dC >= 0 && col + dC < INPUT[0].length) + && q.push( { c: c + INPUT[row + dR][col + dC], row: row + dR, col: col + dC, dR, dC, m: m + 1 }) || 1) + && ((m >= 4 || (dR === 0 && dC === 0)) && [[0, 1], [1, 0], [0, -1], [-1, 0]].forEach(([nDR, nDC]) => ( + (JSON.stringify([nDR, nDC]) !== JSON.stringify([dR, dC])) && (JSON.stringify([nDR, nDC]) !== JSON.stringify([-dR, -dC]))) + && (row + nDR >= 0 && row + nDR < INPUT.length && col + nDC >= 0 && col + nDC < INPUT[0].length) + && q.push({ c: c + INPUT[row + nDR][col + nDC], row: row + nDR, col: col + nDC, dR: nDR, dC: nDC, m: 1 }), + )); +} const pEnd = performance.now(); -console.log(": " + result); +console.log("NEW LEAST HEAT LOSS: " + res); console.log(pEnd - pStart);