Last active
December 13, 2024 08:23
-
-
Save ZeikJT/ed02b7d569f3738dc8e1e63fbc6b6064 to your computer and use it in GitHub Desktop.
Advent of Code 2024
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day01_Part1(str) { | |
const numsLeft = [] | |
const numsRight = [] | |
str.trim().split('\n').forEach((line) => { | |
const [numLeft,numRight] = line.split(/\s+/) | |
numsLeft.push(Number(numLeft)) | |
numsRight.push(Number(numRight)) | |
}) | |
const numSort = (a,b) => a < b ? -1 : 1 | |
numsLeft.sort(numSort) | |
numsRight.sort(numSort) | |
return numsLeft.reduce((totalDiff,_,i) => totalDiff + Math.abs(numsLeft[i] - numsRight[i]), 0) | |
} | |
function adventOfCode2024_Day01_Part2(str) { | |
const numsLeft = [] | |
const numsRight = [] | |
str.trim().split('\n').forEach((line) => { | |
const [numLeft,numRight] = line.split(/\s+/) | |
numsLeft.push(Number(numLeft)) | |
numsRight.push(Number(numRight)) | |
}) | |
const numSort = (a,b) => a < b ? -1 : 1 | |
numsLeft.sort(numSort) | |
numsRight.sort(numSort) | |
return numsLeft.reduce((totalDiff,val) => totalDiff + (numsRight.filter((num) => val === num).length * val), 0) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day02_Part1(str) { | |
const lines = str.trim().split('\n').map((line) => line.split(' ').map((str) => Number(str))) | |
return lines.reduce((totalSafe, nums) => { | |
let dir = 0 | |
for (let i = 0; i < nums.length - 1; i++) { | |
const diff = nums[i] - nums[i + 1] | |
const curDir = Math.sign(diff) | |
const curDiff = Math.abs(diff) | |
if ((dir !== 0 && dir !== curDir) || (curDiff < 1 || curDiff > 3)) { | |
return totalSafe | |
} | |
dir = curDir | |
} | |
return 1 + totalSafe | |
}, 0) | |
} | |
function adventOfCode2024_Day02_Part2(str) { | |
const lines = str.trim().split('\n').map((line) => line.split(' ').map((str) => Number(str))) | |
function cloneAndRemoveIndex(arr, i) { | |
return arr.filter((_, idx) => idx !== i) | |
} | |
function checkNums(nums) { | |
let dir = 0 | |
for (let i = 0; i < nums.length - 1; i++) { | |
const diff = nums[i] - nums[i + 1] | |
const curDir = Math.sign(diff) | |
const curDiff = Math.abs(diff) | |
if ((dir !== 0 && dir !== curDir) || (curDiff < 1 || curDiff > 3)) { | |
return i | |
} | |
dir = curDir | |
} | |
return -1 | |
} | |
return lines.reduce((totalSafe, nums) => { | |
const result = checkNums(nums) | |
if (result !== -1) { | |
if ((result !== 1 || checkNums(cloneAndRemoveIndex(nums, 0)) !== -1) && | |
checkNums(cloneAndRemoveIndex(nums, result)) !== -1 && | |
checkNums(cloneAndRemoveIndex(nums, result + 1)) !== -1) { | |
return totalSafe | |
} | |
} | |
return 1 + totalSafe | |
}, 0) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day03_Part1(str) { | |
let total = 0 | |
for (const {groups: {n1, n2}} of str.trim().matchAll(/mul\((?<n1>\d+),(?<n2>\d+)\)/g)) { | |
total += Number(n1) * Number(n2) | |
} | |
return total | |
} | |
function adventOfCode2024_Day03_Part2(str) { | |
let total = 0 | |
let enabled = true | |
for (const {groups: {n1, n2, enable}} of str.trim().matchAll(/mul\((?<n1>\d+),(?<n2>\d+)\)|(?<enable>do(?:n\'t)?)\(\)/g)) { | |
if (enable) { | |
enabled = enable === 'do' | |
} else if (enabled) { | |
total += Number(n1) * Number(n2) | |
} | |
} | |
return total | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day04_Part1(str) { | |
const find = 'XMAS' | |
const findR = (() => { | |
const letters = find.split('') | |
letters.reverse() | |
return letters.join('') | |
})() | |
const findWords = [find, findR] | |
let total = 0 | |
const lines = str.trim().split('\n') | |
const lineLen = lines[0].length | |
const linesVert = lines[0].split('').map(() => []) | |
const linesSW = [] | |
const linesSE = [] | |
// Vert, SW and SE top | |
for (let i = 0; i < lineLen; i++) { | |
for (const line of lines) { | |
linesVert[i].push(line[i]) | |
} | |
if (i >= find.length - 1) { | |
const newSELine = [] | |
const newSWLine = [] | |
for (let j = i, l = 0; j >= 0, l < lines.length; j--, l++) { | |
newSWLine.push(lines[l][j]) | |
newSELine.push(lines[l][lineLen - j - 1]) | |
} | |
linesSW.push(newSWLine.join('')) | |
linesSE.push(newSELine.join('')) | |
} | |
linesVert[i] = linesVert[i].join('') | |
} | |
// SW and SE sides | |
for (let j = 1; j <= lines.length - 4; j++) { | |
const newSELine = [] | |
const newSWLine = [] | |
for (let i = 0, l = j; i < lineLen, l < lines.length; i++, l++) { | |
newSELine.push(lines[l][i]) | |
newSWLine.push(lines[l][lineLen - i - 1]) | |
} | |
linesSW.push(newSWLine.join('')) | |
linesSE.push(newSELine.join('')) | |
} | |
for (const linesToCheck of [lines, linesVert, linesSW, linesSE]) { | |
for (const line of linesToCheck) { | |
total += [...line.matchAll(new RegExp(find, 'g')), ...line.matchAll(new RegExp(findR, 'g'))].length | |
} | |
} | |
return total | |
} | |
function adventOfCode2024_Day04_Part2(str) { | |
const find = 'MAS' | |
const l1 = find[0] | |
const l2 = find[1] | |
const l3 = find[2] | |
const possibilities = [ | |
`${l1}${l1}${l3}${l3}`, | |
`${l1}${l3}${l3}${l1}`, | |
`${l3}${l3}${l1}${l1}`, | |
`${l3}${l1}${l1}${l3}`, | |
] | |
const lines = str.trim().split('\n') | |
const lineLen = lines[0].length | |
let total = 0 | |
for (let l = 1; l < lines.length - 1; l++) { | |
for (let i = 1; i < lineLen - 1; i++) { | |
if (lines[l][i] === l2 && possibilities.includes(`${lines[l-1][i-1]}${lines[l-1][i+1]}${lines[l+1][i+1]}${lines[l+1][i-1]}`)) { | |
total += 1 | |
} | |
} | |
} | |
return total | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day05_Part1(str) { | |
const sections = str.trim().split('\n\n') | |
const befores = sections[0].split('\n').map((line) => line.split('|').map((str) => Number(str))) | |
const lines = sections[1].split('\n').map((line) => line.split(',').map((str) => Number(str))) | |
const afterBeforeMap = new Map() | |
for (const [before,after] of befores) { | |
if (!afterBeforeMap.has(before)) { | |
afterBeforeMap.set(before, [after]) | |
} else { | |
afterBeforeMap.set(before, [...afterBeforeMap.get(before), after]) | |
} | |
} | |
let total = 0 | |
outer: for (const line of lines) { | |
const seen = new Set() | |
for (const num of line) { | |
if (afterBeforeMap.get(num)?.some((after) => seen.has(after)) ?? false) { | |
continue outer | |
} | |
seen.add(num) | |
} | |
total += line[Math.floor(line.length / 2)] | |
} | |
return total | |
} | |
function adventOfCode2024_Day05_Part2(str) { | |
const sections = str.trim().split('\n\n') | |
const befores = sections[0].split('\n').map((line) => line.split('|').map((str) => Number(str))) | |
const lines = sections[1].split('\n').map((line) => line.split(',').map((str) => Number(str))) | |
const beforeAfterMap = new Map() | |
for (const [before, after] of befores) { | |
if (!beforeAfterMap.has(after)) { | |
beforeAfterMap.set(after, [before]) | |
} else { | |
beforeAfterMap.set(after, [...beforeAfterMap.get(after), before]) | |
} | |
} | |
let total = 0 | |
for (const line of lines) { | |
let outOfOrder = false | |
const resortedLine = [] | |
for (const num of line) { | |
const insertIndex = resortedLine.findIndex((seenNum) => beforeAfterMap.get(seenNum)?.some((before) => num === before)) | |
if (insertIndex !== -1) { | |
resortedLine.splice(insertIndex, 0, num) | |
outOfOrder = true | |
} else { | |
resortedLine.push(num) | |
} | |
} | |
if (outOfOrder) { | |
total += resortedLine[Math.floor(resortedLine.length / 2)] | |
} | |
} | |
return total | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day06_Part1(str) { | |
const map = str.trim().split('\n') | |
const width = map[0].length | |
const height = map.length | |
const walked = new Set() | |
const pos = {x: -1, y: -1} | |
const dir = {x: 0, y: -1} | |
for (const [y, row] of map.entries()) { | |
const x = row.indexOf('^') | |
if (x !== -1) { | |
pos.x = x | |
pos.y = y | |
//map[y] = row.replace('^', '.') | |
break | |
} | |
} | |
while (pos.x >= 0 && pos.x < width && pos.y >= 0 && pos.y < height) { | |
/* Debug | |
map[pos.y] = map[pos.y].substring(0, pos.x) + 'X' + map[pos.y].substring(pos.x + 1) | |
document.body.children[0].textContent = map.join('\n') | |
//*/ | |
walked.add(`${pos.y},${pos.x}`) | |
while (map[pos.y + dir.y]?.[pos.x + dir.x] === '#') { | |
const {x,y} = dir | |
dir.x = y * -1 | |
dir.y = x | |
} | |
pos.x += dir.x | |
pos.y += dir.y | |
} | |
return walked.size | |
} | |
function adventOfCode2024_Day06_Part2(str) { | |
const defaultMap = str.trim().split('\n') | |
const width = defaultMap[0].length | |
const height = defaultMap.length | |
const startPos = {x: -1, y: -1} | |
const dirs = [ | |
{x:1,y:0}, | |
{x:-1,y:0}, | |
{x:0,y:1}, | |
{x:0,y:-1}, | |
] | |
for (const [y, row] of defaultMap.entries()) { | |
const x = row.indexOf('^') | |
if (x !== -1) { | |
startPos.x = x | |
startPos.y = y | |
break | |
} | |
} | |
possibleObstacles = new Set() | |
function isInMap(pos) { | |
return pos.x >= 0 && pos.x < width && pos.y >= 0 && pos.y < height | |
} | |
function vec2ToStr(vec2) { | |
return `${vec2.x},${vec2.y}` | |
} | |
function walk(map = defaultMap, pos = startPos, dir = {x: 0, y: -1}, walked = new Set(), turns = new Map(dirs.map((vec2) => [vec2ToStr(vec2), new Set()])), addObstacles = true) { | |
while (isInMap(pos)) { | |
walked.add(vec2ToStr(pos)) | |
while (map[pos.y + dir.y]?.[pos.x + dir.x] === '#') { | |
const turned = turns.get(vec2ToStr(dir)) | |
if (turned.has(vec2ToStr(pos))) { | |
return true // looped | |
} | |
turned.add(vec2ToStr(pos)) | |
const {x,y} = dir | |
dir.x = y * -1 | |
dir.y = x | |
} | |
const dest = {x: pos.x + dir.x, y: pos.y + dir.y} | |
if (addObstacles && !walked.has(vec2ToStr(dest)) && isInMap(dest)) { | |
const speculativeMap = map.with(dest.y, map[dest.y].slice(0, dest.x) + '#' + map[dest.y].slice(dest.x + 1)) | |
const speculativeTurns = new Map() | |
for (const [turn, positions] of turns.entries()) { | |
speculativeTurns.set(turn, new Set(positions)) | |
} | |
if (walk(speculativeMap, Object.assign({}, pos), Object.assign({}, dir), new Set(walked), speculativeTurns, false)) { | |
possibleObstacles.add(vec2ToStr(dest)) | |
} | |
} | |
pos.x += dir.x | |
pos.y += dir.y | |
} | |
return false // didn't loop | |
} | |
if (walk()) { | |
throw new Error(`main map walking shouldn't loop`) | |
} | |
return possibleObstacles | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day07_Part1(str) { | |
const data = str.trim().split('\n').map((line) => line.split(/:? /).map(Number)) | |
let total = 0 | |
for (const [testValue, ...nums] of data) { | |
const max = Math.pow(2, nums.length - 1) | |
for (let bits = 0; bits < max; bits++) { | |
let calc = nums[0] | |
const bitStr = bits.toString(2).padStart(nums.length - 1, '0') | |
for (let i = 1; i < nums.length; i++) { | |
if (bitStr[i - 1] === '1') { | |
calc *= nums[i] | |
} else { | |
calc += nums[i] | |
} | |
} | |
if (calc === testValue) { | |
total += testValue | |
break | |
} | |
} | |
} | |
return total | |
} | |
function adventOfCode2024_Day07_Part2(str) { | |
const data = str.trim().split('\n').map((line) => line.split(/:? /).map(Number)) | |
const ops = ['+', '*', '||'] | |
// Adapted from https://stackoverflow.com/a/75016688 | |
function createCombinations(ops, size) { | |
const combinations = [] | |
function generateCombinations(ops, combination) { | |
if (combination.length === size) { | |
combinations.push(combination) | |
} else { | |
for (let i = 0; i < ops.length; i++) { | |
const newCombination = [...combination, ops[i]] | |
generateCombinations(ops, newCombination) | |
} | |
} | |
} | |
generateCombinations(ops, []) | |
return combinations | |
} | |
let total = 0 | |
for (const [testValue, ...nums] of data) { | |
const operations = createCombinations(ops, nums.length - 1) | |
for (const operation of operations) { | |
let calc = nums[0] | |
for (let i = 1; i < nums.length; i++) { | |
switch (operation[i - 1]) { | |
case '+': | |
calc += nums[i] | |
break | |
case '*': | |
calc *= nums[i] | |
break | |
case '||': | |
calc = Number(`${calc}${nums[i]}`) | |
break | |
} | |
} | |
if (calc === testValue) { | |
total += testValue | |
break | |
} | |
} | |
} | |
return total | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day08_Part1(str) { | |
const map = str.trim().split('\n') | |
const width = map[0].length | |
const height = map.length | |
const antennae = new Map() | |
const antinodes = new Set() | |
for (const [y, line] of map.entries()) { | |
for (const [x, char] of line.split('').entries()) { | |
const pos = [x,y] | |
if (char !== '.') { | |
if (!antennae.has(char)) { | |
antennae.set(char, [pos]) | |
} else { | |
const a = antennae.get(char) | |
for (const prev of a) { | |
const dist = [pos[0] - prev[0], pos[1] - prev[1]] | |
const antis = [ | |
[pos[0] + dist[0], pos[1] + dist[1]], | |
[prev[0] - dist[0], prev[1] - dist[1]], | |
] | |
for (const anti of antis) { | |
if (anti[0] >= 0 && anti[0] < width && anti[1] >= 0 && anti[1] < height) { | |
antinodes.add(`${anti[0]},${anti[1]}`) | |
} | |
} | |
} | |
a.push(pos) | |
} | |
} | |
} | |
} | |
return antinodes.size | |
} | |
function adventOfCode2024_Day08_Part2(str) { | |
const map = str.trim().split('\n') | |
const width = map[0].length | |
const height = map.length | |
const antennae = new Map() | |
const antinodes = new Set() | |
for (const [y, line] of map.entries()) { | |
for (const [x, char] of line.split('').entries()) { | |
const pos = [x,y] | |
if (char !== '.') { | |
if (!antennae.has(char)) { | |
antennae.set(char, [pos]) | |
} else { | |
const a = antennae.get(char) | |
for (const prev of a) { | |
const dist = [pos[0] - prev[0], pos[1] - prev[1]] | |
const antis = [ | |
[pos.slice(), dist], | |
[prev.slice(), [dist[0] * -1, dist[1] * -1]] | |
] | |
for (const [anti, dist] of antis) { | |
while (anti[0] >= 0 && anti[0] < width && anti[1] >= 0 && anti[1] < height) { | |
antinodes.add(`${anti[0]},${anti[1]}`) | |
anti[0] += dist[0] | |
anti[1] += dist[1] | |
} | |
} | |
} | |
a.push(pos) | |
} | |
} | |
} | |
} | |
return antinodes.size | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day09_Part1(str) { | |
let id = 0 | |
let file = true | |
const layout = [] | |
for (const char of str.trim()) { | |
const num = Number(char) | |
layout.push(...new Array(num).fill(file ? id++ : '.')) | |
file = !file | |
} | |
let j = layout.length - 1 | |
let checksum = 0 | |
for (let i = 0; i < layout.length; i++) { | |
if (layout[i] === '.') { | |
while (layout[j] === '.') { | |
j-- | |
} | |
if (i < j) { | |
layout[i] = layout[j] | |
layout[j] = '.' | |
} | |
} | |
if (layout[i] !== '.') { | |
checksum += i * layout[i] | |
} | |
if (i >= j) { | |
break | |
} | |
} | |
return checksum | |
} | |
function adventOfCode2024_Day09_Part2(str) { | |
let id = 0 | |
let file = true | |
const layout = [] | |
for (const char of str.trim()) { | |
const num = Number(char) | |
layout.push(file ? [{id: id++, num}] : num) | |
file = !file | |
} | |
let data = layout.length - 1 & 1 == 1 ? layout.length - 2 : layout.length - 1 | |
let empty = 1 | |
for (; data > empty; data -= 2) { | |
for (let e = empty; e < data; e += 2) { | |
const size = layout[data][0].num | |
if (layout[e] >= size) { | |
layout[e] -= size | |
layout[data - 1] += size | |
layout[e - 1].push(layout[data].shift()) | |
while (layout[empty] === 0) { | |
empty += 2 | |
} | |
break | |
} | |
} | |
} | |
let checksum = 0 | |
let index = 0 | |
for (let i = 0; i < layout.length; i++) { | |
if (i & 1 === 1) { | |
index += layout[i] | |
} else { | |
for (const {id,num} of layout[i]) { | |
for (let n = 0; n < num; n++) { | |
checksum += (index + n) * id | |
} | |
index += num | |
} | |
} | |
} | |
return checksum | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day10_Part1(str) { | |
const map = str.trim().split('\n').map((line) => line.split('').map(Number)) | |
const height = map.length | |
const width = map[0].length | |
let score = 0 | |
const neighborLocations = [ | |
[-1, 0], | |
[ 0, -1], | |
[ 0, 1], | |
[ 1, 0], | |
] | |
function followNeighborPath(py, px, num, nines = new Set) { | |
for (const [oy, ox] of neighborLocations) { | |
const y = py + oy | |
const x = px + ox | |
if (map[y]?.[x] === num) { | |
if (num === 9) { | |
nines.add(`${y},${x}`) | |
} else { | |
followNeighborPath(y, x, num + 1, nines) | |
} | |
} | |
} | |
return nines | |
} | |
let nines = 0 | |
for (let y = 0; y < height; y++) { | |
for (let x = 0; x < width; x++) { | |
if (map[y][x] === 0) { | |
nines += followNeighborPath(y, x, 1).size | |
} | |
} | |
} | |
return nines | |
} | |
function adventOfCode2024_Day10_Part2(str) { | |
const map = str.trim().split('\n').map((line) => line.split('').map(Number)) | |
const height = map.length | |
const width = map[0].length | |
let score = 0 | |
const neighborLocations = [ | |
[-1, 0], | |
[ 0, -1], | |
[ 0, 1], | |
[ 1, 0], | |
] | |
function followNeighborPath(py, px, num) { | |
let nines = 0 | |
for (const [oy, ox] of neighborLocations) { | |
const y = py + oy | |
const x = px + ox | |
if (map[y]?.[x] === num) { | |
if (num === 9) { | |
nines++ | |
} else { | |
nines += followNeighborPath(y, x, num + 1) | |
} | |
} | |
} | |
return nines | |
} | |
let nines = 0 | |
for (let y = 0; y < height; y++) { | |
for (let x = 0; x < width; x++) { | |
if (map[y][x] === 0) { | |
nines += followNeighborPath(y, x, 1) | |
} | |
} | |
} | |
return nines | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day11_Part1(str) { | |
let nums = str.trim().split(' ').map(Number) | |
for (let i = 0; i < 25; i++) { | |
let newNums = [] | |
for (const num of nums) { | |
if (num === 0) { | |
newNums.push(1) | |
} else if ((String(num).length & 1) === 0) { | |
const strNum = String(num) | |
const half = Math.floor(strNum.length / 2) | |
newNums.push(Number(strNum.slice(0, half)), Number(strNum.slice(half))) | |
} else { | |
newNums.push(num * 2024) | |
} | |
} | |
nums = newNums | |
} | |
return nums.length | |
} | |
function adventOfCode2024_Day11_Part2(str) { | |
let nums = str.trim().split(' ').map(Number) | |
const memo = new Map() | |
let numCount = 0 | |
function calc(num, iters) { | |
if (iters === 0) { | |
return 1 | |
} | |
const id = `${num};${iters}` | |
if (memo.has(id)) { | |
return memo.get(id) | |
} | |
let res | |
if (num === 0) { | |
res = calc(1, iters - 1) | |
} else if ((String(num).length & 1) === 0) { | |
const strNum = String(num) | |
const half = Math.floor(strNum.length / 2) | |
res = calc(Number(strNum.slice(0, half)), iters - 1) + calc(Number(strNum.slice(half)), iters - 1) | |
} else { | |
res = calc(num * 2024, iters - 1) | |
} | |
memo.set(id, res) | |
return res | |
} | |
for (const num of nums) { | |
numCount += calc(num, 75) | |
} | |
return numCount | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function adventOfCode2024_Day13_Part1(str) { | |
const data = str.trim().split('\n\n').map((section) => section.split('\n').map((line) => { | |
const {x,y} = /X[+=](?<x>\d+), Y[+=](?<y>\d+)/.exec(line).groups | |
return {x: Number(x), y: Number(y)} | |
})) | |
let tokens = 0 | |
for (const [a,b,total] of data) { | |
const bmax = Math.floor(total.x / b.x) | |
let lowestTokens = 0 | |
for (let bi = bmax; bi >= 0; bi--) { | |
if (((total.x - (bi * b.x)) % a.x) === 0) { | |
const afill = (total.x - (bi * b.x)) / a.x | |
if (((bi * b.y) + (afill * a.y)) === total.y) { | |
const cost = bi + (afill * 3) | |
if (cost < lowestTokens || !lowestTokens) { | |
lowestTokens = cost | |
} | |
} | |
} | |
} | |
tokens += lowestTokens | |
} | |
return tokens | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Didn't read the example code close enough to realize loops don't have a be a single 4 anchor shape, could be two 3 anchor shapes or more. | |
function adventOfCode2024_Day06_Part2(str) { | |
function indexOfOr(str, find, start, orDefault) { | |
const res = str.indexOf(find, start) | |
return res === -1 ? orDefault : res | |
} | |
const map = str.trim().split('\n') | |
const width = map[0].length | |
const height = map.length | |
const vmap = (() => { | |
const arr = new Array(width).fill(0).map(() => ['']) | |
for (let c = 0; c < width; c++) { | |
for (let r = 0; r < height; r++) { | |
arr[c] += map[r][c] | |
} | |
} | |
return arr | |
})() | |
const min = 4 | |
const possibleLoops = [] | |
for (let r = 0; r <= height - min; r++) { | |
if (r === 6) debugger | |
for (let c = 0; c <= width - min; c++) { | |
const maxWidthT = indexOfOr(map[r + 1], '#', c + 1, width - 1) | |
const maxHeightT = indexOfOr(vmap[c + 1], '#', r + 1, height - 1) | |
for (let mr = r + min - 1; mr <= maxHeightT; mr++) { | |
const maxWidthB = indexOfOr(map[mr - 1], '#', c + 1, width - 1) | |
for (let mc = c + min - 1; mc <= maxWidthT && mc <= maxWidthB; mc++) { | |
const maxHeightB = indexOfOr(vmap[mc -1], '#', r + 1, height - 1) | |
if (maxHeightB < mr) continue // obstacle | |
let cornerCount = 0 | |
const types = [] | |
if (map[r][c + 1] === '#') {types.push('TL');cornerCount++} // top left | |
if (map[mr - 1][c] === '#') {types.push('BL');cornerCount++} // bottom left | |
if (map[r + 1][mc] === '#') {types.push('TR');cornerCount++} // top right | |
if (map[mr][mc - 1] === '#') {types.push('BR');cornerCount++} // bottom right | |
if (cornerCount === 4) { | |
throw new Error('pre-existing loops, not written to handle') | |
} | |
if (cornerCount === 3) { | |
possibleLoops.push({c, r, mc, mr}) | |
console.log({c, r, mc, mr}, types) | |
console.log(map.slice(r, mr + 1).map((str) => str.slice(c, mc + 1)).join('\n')) | |
} | |
} | |
} | |
} | |
} | |
return possibleLoops | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment