import 2024

This commit is contained in:
2025-11-11 03:36:04 +01:00
parent 31a3bebe63
commit a92b8a7cd9
24 changed files with 1087 additions and 0 deletions

38
src/2024/1/1/index.ts Normal file
View File

@@ -0,0 +1,38 @@
import fs from 'node:fs';
const listOne: number[] = [];
const listTwo: number[] = [];
const listDiff: number[] = [];
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
data.split('\n').forEach(line => {
if (line.trim() === '') return;
const spLine = line.split(' ');
if (!spLine[0] || !spLine[1]) throw new Error()
listOne.push(parseInt(spLine[0]))
listTwo.push(parseInt(spLine[1]))
})
listOne.sort((a, b) => a - b)
listTwo.sort((a, b) => a - b)
if (listOne.length != listTwo.length || !listOne || !listTwo) {
throw `Different length of list \n 01: ${listOne.length}, 02: ${listTwo.length}`
}
for (let i = 0; i < listTwo.length; i++) {
let diff = ((listOne[i] ?? 0) - (listTwo[i] ?? 0));
if (diff < 0) diff *= -1
listDiff.push(diff)
}
let sum = 0;
listDiff.forEach(value => {
sum += value
})
console.log(sum)
})
}

37
src/2024/1/2/index.ts Normal file
View File

@@ -0,0 +1,37 @@
import fs from 'node:fs';
const listOne: number[] = [];
const listTwo: number[] = [];
const map: Map<number, number> = new Map();
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
data.split('\n').forEach(line => {
if (line.trim() === '') return;
const spLine = line.split(' ');
if (!spLine[0] || !spLine[1]) throw new Error()
listOne.push(parseInt(spLine[0]))
listTwo.push(parseInt(spLine[1]))
})
for(let i = 0; i<listTwo.length; i++){
let k = listTwo[i] ?? 0;
let v = 0;
if(map.has(k)) v = map.get(k) ?? 0
v++
map.set(k, v);
}
let sum = 0
for(let i = 0; i<listOne.length; i++){
let v = listOne[i] ?? 0
if(!map.has(v)) continue;
let n = v*(map.get(v)??0);
sum += n;
}
console.log(sum)
})
}

50
src/2024/10/1/index.ts Normal file
View File

@@ -0,0 +1,50 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', async (err, data) => {
if (err) throw err;
let count = 0;
let grid: number[][] = []
data.split("\n").forEach((value, index) => {
for (let i = 0; i < value.length; i++) {
if (grid[i] === undefined) grid[i] = []
if (grid[i] === undefined) throw new Error();
// @ts-ignore
grid[i][index] = parseInt(value.charAt(i))
}
})
for (let x = 0; x < grid.length; x++) {
// @ts-ignore
for (let y = 0; y < grid[x].length; y++) {
const found = findWord(grid, x, y, 0)
count+=found;
}
}
console.log(count)
})
}
function findWord(grid: number[][], x: number, y: number, elevation: number): number {
// @ts-ignore
if (x < 0 || x === grid.length || y < 0 || y === grid[x].length) {
return 0;
}
// @ts-ignore
if (grid[x][y] === elevation) {
if(elevation === 9) return 1
let found = 0;
for (let dX = -1; dX < 2; dX++) {
for (let dY = -1; dY < 2; dY++) {
if (dX === 0 && dY === 0) continue;
if(dX !== 0 && dY !== 0) continue;
found += findWord(grid, x + dX, y + dY, elevation+1);
}
}
return found;
} else {
return 0;
}
}

0
src/2024/10/2/index.ts Normal file
View File

25
src/2024/11/1/index.ts Normal file
View File

@@ -0,0 +1,25 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', async (err, data) => {
if (err) throw err;
let stones: number[] = data.split(" ").map<number>(value => parseInt(value))
for (let x = 0; x < 25; x++) {
let newstones: number[] = []
stones.forEach((value) => {
if(value === 0) {
newstones.push(1);
} else if(value.toString().length%2 !== 1) {
newstones.push(parseInt(value.toString().slice(0, value.toString().length/2)))
newstones.push(parseInt(value.toString().slice(value.toString().length/2 , value.toString().length)))
} else {
newstones.push(value*2024)
}
})
stones = newstones
}
console.log(stones.length)
})
}

40
src/2024/11/2/index.ts Normal file
View File

@@ -0,0 +1,40 @@
import fs from 'node:fs';
const cache: Map<string, number> = new Map();
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', async (err, data) => {
if (err) throw err;
let stones: string[] = data.split(" ")
let count: number = 0
stones.forEach(stone => {count+=solveStone(stone, 75)})
console.log(count)
})
}
function solveStone(input: string, depth: number): number{
const cachekey = `${input};${depth}`
if(depth === 0) return 1;
if(cache.has(cachekey)) {
return cache.get(cachekey)??0
}
if(parseInt(input) === 0) {
const result = solveStone("1", depth-1)
cache.set(cachekey, result)
return result
} else if(input.length%2 !== 1) {
const slicepoint = input.length/2
const stoneA: number = solveStone(input.slice(0, slicepoint), depth-1)
const stoneB: number = solveStone(input.slice(slicepoint), depth-1)
const result = stoneA+stoneB
cache.set(cachekey, result)
return result
} else {
const result = solveStone((parseInt(input)*2024).toString(), depth-1)
cache.set(cachekey, result)
return result
}
}

69
src/2024/12/1/index.ts Normal file
View File

@@ -0,0 +1,69 @@
import fs from 'node:fs';
type FenceArea = {price: number, area: number, fence: number}
type Vec2d = {x: number, y: number}
const calculationIndex: Set<string> = new Set();
const neighbors: Vec2d[] = [{x: -1, y: 0}, {x: 0, y: -1}, {x: 0, y: 1}, {x:1, y:0}]
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', async (err, data) => {
if (err) throw err;
const rows: string[] = data.split("\n")
const grid: string[][] = rows.map(row => [...row])
let cost = 0;
grid.forEach((row, rowIndex) => {
row.forEach((value, colIndex) => {
if(grid[colIndex] === undefined) grid[colIndex] = []
grid[colIndex][rowIndex] = value
})
})
/*for (let x = 0; x < grid.length; x++) {
for (let y = 0; y < (grid[x]??[]).length; y++) {
if(calculationIndex.has(`${x};${y}`)) continue
const r = calculateFencePrice(grid, x, y)
console.log(r)
cost += r.price
}
}*/
const r = calculateFencePrice(grid, 0, 0)
console.log(r)
cost += r.price
console.log(cost)
})
}
function calculateFencePrice(grid: string[][], x: number, y: number, previous: string = "", lookupindex: Set<string> = new Set()): FenceArea {
let area: number = 1, fence: number = 0
if(x<0 || y<0 || grid.length<x || (grid[x]??[]).length<y) return {price: 0, area: 0, fence: 1};
const current = ((grid[x]??[])[y])??""
if(current !== previous && previous !== "") return {area: 0, price: 0, fence: 1}
if (lookupindex.has(`${x};${y}`)) return {price: 0, fence: 0, area: 0}
console.log(x,y, lookupindex)
lookupindex.add(`${x};${y}`)
if(current === previous) {
calculationIndex.add(`${x};${y}`)
}
for (const n of neighbors) {
const r = calculateFencePrice(grid, x+n.x, y+n.y, current, lookupindex)
fence += r.fence
area += r.area
}
return {fence: fence, area: area, price: fence*area}
}

60
src/2024/16/1/index.ts Normal file
View File

@@ -0,0 +1,60 @@
import fs from 'node:fs';
type Vec2d = {x: number, y: number};
const directions: Vec2d[] = [ {x: 1, y: 0}, {x: 0, y: 1}, {x:-1, y:0}, {x: 0, y: -1}]
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', async (err, data) => {
if (err) throw err;
let grid: boolean[][] = []
let start: Vec2d
let end: Vec2d
data.split("\n").forEach((value, index) => {
for (let i = 0; i < value.length; i++) {
if (grid[i] === undefined) grid[i] = [];
(grid[i]??[])[index] = value.charAt(i)==='#'
if(value.charAt(i) === 'S') start={x: i, y: index}
if(value.charAt(i) === 'E') end={x: i, y: index}
}
})
const count: number = solve(start, end)
console.log(count)
})
}
function solve(start: Vec2d, end: Vec2d): number {
let r :number = 0
return r
}
function move(location: Vec2d, direction: number, grid: boolean[][]): number {
const newLocation: Vec2d = {x: location.x, y: location.y}
newLocation.x += (directions[direction]??{x: 0, y: 1}).x
newLocation.y += (directions[direction]??{x: 0, y: 1}).y
if(grid[newLocation.x]??[][newLocation.y]) return -1;
location = newLocation;
const m:number = move(location, direction, grid)
const t:number = turn(location, direction, grid)
if(m===-1 && t === -1) return -1;
if(m===-1) return t;
if(t===-1) return m;
return (m<t ? m : t)
}
function turn(location: Vec2d, direction: number, grid: boolean[][]): number {
direction = (direction +1)%4
const m:number = move(location, direction, grid)
const t:number = turn(location, direction, grid)
if(m===-1 && t === -1) return -1;
if(m===-1) return t;
if(t===-1) return m;
return (m<t ? m : t)
}

46
src/2024/2/1/index.ts Normal file
View File

@@ -0,0 +1,46 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`${input}`, 'utf8', (err, data) => {
if (err) throw err;
let count = 0;
data.split('\n').forEach((line, index, lines) => {
if(line.trim() === '') return;
let safe = true;
let positive = undefined;
const spLine = line.split(' ');
if (!spLine[0] || !spLine[1]) throw new Error()
for(let i = 0; i<spLine.length-1;i++){
if(!spLine[i] || !spLine[i+1]) throw new Error();
if (!safe) continue;
let i1 = parseInt((spLine[i]??"0"))
let i2 = parseInt((spLine[i+1]??"0"))
console.log(`i1: ${i1} | i2: ${i2} | diff: ${i1-i2} | safe: ${safe}`)
if(i1-i2>3 || i2-i1>3 || i2-i1 == 0) {
safe = false;
continue;
}
if(i1-i2 > 0) {
if(!positive && positive !== undefined){
safe = false;
continue;
}
positive = true;
}
if(i1-i2 < 0) {
if(positive){
safe = false;
continue;
}
positive = false;
}
}
if(safe) count++
console.log(`---- safe=${count} ----`)
})
console.log(count)
})
}

63
src/2024/2/2/index.ts Normal file
View File

@@ -0,0 +1,63 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`${input}`, 'utf8', (err, data) => {
if (err) throw err;
let count = 0;
data.split('\n').forEach(line => {
if(line.trim() === '') return;
const spLine = line.split(' ');
let safe = checkIsSafe(spLine)
if(safe) count++
if(!safe){
let safeMinusOne = false;
for(let j = 0; j<spLine.length; j++){
if(safeMinusOne) continue;
console.log(`-- unsafe - checking without value #${j} --`)
let spLineF = spLine;
spLineF = spLineF.filter((_value, index) => index !== j);
safeMinusOne = checkIsSafe(spLineF)
}
if(safeMinusOne) {
safe = safeMinusOne
count++
}
}
if (safe) console.log(`---- safe=${count} ----`)
if (!safe) console.log("---- unsafe, even filtered ----")
})
console.log(count)
})
}
function checkIsSafe(spLine:string[]){
let safe = true;
let positive = undefined;
if (!spLine[0] || !spLine[1]) throw new Error()
for(let i = 0; i<spLine.length-1;i++){
if (!safe) continue;
if(!spLine[i] || !spLine[i+1]) throw new Error();
let i1 = parseInt((spLine[i]??"0"))
let i2 = parseInt((spLine[i+1]??"0"))
if(i1-i2>3 || i2-i1>3 || i2-i1 == 0) {
safe = false;
}
if(i1-i2 > 0) {
if(!positive && positive !== undefined){
safe = false;
}
positive = true;
}
if(i1-i2 < 0) {
if(positive){
safe = false;
}
positive = false;
}
console.log(`i1: ${i1} | i2: ${i2} | diff: ${i1-i2} | safe: ${safe} | positive: ${positive}`)
}
return safe;
}

24
src/2024/3/1/index.ts Normal file
View File

@@ -0,0 +1,24 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
let count = 0;
const regex = /mul\((?<a>\d{1,3}),(?<b>\d{1,3})\)/gm;
let m;
while ((m = regex.exec(data)) !== null) {
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
count += parseInt(m[1]??"")*parseInt(m[2]??"")
}
console.log(count)
})
}

27
src/2024/3/2/index.ts Normal file
View File

@@ -0,0 +1,27 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
let count = 0;
data.split("do()").forEach(value => {
value.split("don't()").forEach((value1, index) => {
if(index != 0) return
const regex = /mul\((?<a>\d{1,3}),(?<b>\d{1,3})\)/gm;
let m;
while ((m = regex.exec(value1)) !== null) {
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
count += parseInt(m[1]??"")*parseInt(m[2]??"")
}
})
})
console.log(count)
})
}

58
src/2024/4/1/index.ts Normal file
View File

@@ -0,0 +1,58 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', async (err, data) => {
if (err) throw err;
let count = 0;
let grid: string[][] = []
data.split("\n").forEach((value, index) => {
for (let i = 0; i < value.length; i++) {
if (grid[i] === undefined) grid[i] = []
if (grid[i] === undefined) throw new Error();
// @ts-ignore
grid[i][index] = value.charAt(i)
}
})
for (let x = 0; x < grid.length; x++) {
// @ts-ignore
for (let y = 0; y < grid[x].length; y++) {
const found = findWord(grid, x, y, "X")
count+=found;
}
}
console.log(count)
})
}
function findWord(grid: string[][], x: number, y: number, char: string, dx: number = 0, dy: number = 0): number {
// @ts-ignore
if (x < 0 || x === grid.length || y < 0 || y === grid[x].length) {
return 0;
}
// @ts-ignore
if (grid[x][y] === char) {
switch (char) {
case 'X':
let found = 0;
for (let dX = -1; dX < 2; dX++) {
for (let dY = -1; dY < 2; dY++) {
if (dX === 0 && dY === 0) continue;
if (findWord(grid, x + dX, y + dY, 'M', dX, dY) != 0) found++;
}
}
return found;
case 'M':
return findWord(grid, x + dx, y + dy, 'A', dx, dy)
case 'A':
return findWord(grid, x + dx, y + dy, 'S', dx, dy)
case 'S':
return 1;
}
} else {
return 0;
}
return 0;
}

43
src/2024/4/2/index.ts Normal file
View File

@@ -0,0 +1,43 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', async (err, data) => {
if (err) throw err;
let count = 0;
let grid: string[][] = []
data.split("\n").forEach((value, index) => {
for (let i = 0; i < value.length; i++) {
if (grid[i] === undefined) grid[i] = []
if (grid[i] === undefined) throw new Error();
// @ts-ignore
grid[i][index] = value.charAt(i)
}
})
for (let x = 0; x < grid.length; x++) {
// @ts-ignore
for (let y = 0; y < grid[x].length; y++) {
const found = findWord(grid, x, y)
if (found) count++;
}
}
console.log(count)
})
}
function findWord(grid: string[][], x: number, y: number): boolean {
// @ts-ignore
if (x < 1 || x === grid.length-1 || y < 1 || y === grid[x].length-1) {
return false;
}
// @ts-ignore
return grid[x][y] === 'A' && ((grid[x-1][y-1] == "M" && grid[x+1][y+1] == 'S') || (grid[x-1][y-1] == "S" && grid[x+1][y+1] == 'M')) && ((grid[x+1][y-1] == "M" && grid[x-1][y+1] == 'S') || (grid[x+1][y-1] == "S" && grid[x-1][y+1] == 'M'))
}
// M . M
// . A .
// S . S

52
src/2024/5/1/index.ts Normal file
View File

@@ -0,0 +1,52 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
const [rawRules, rawPages] = data.split('\n\n')
var rules :Map<string, number> = new Map();
const parsedRules = (rawRules??"").split("\n")
parsedRules.map(pRule => {
const [v1, v2] = pRule.split("|")
rules.set(pRule, -1)
rules.set(`${v2}|${v1}`, 1)
})
let splitPages = (rawPages??"").split("\n")
splitPages = splitPages.filter(value => {
const aPages = value.split(",");
const bPages = value.split(",");
aPages.sort((a, b) => {
return rules.get(`${a}|${b}`)??0
})
return compareArrays(aPages, bPages);
})
console.log(splitPages)
let sum = 0;
splitPages.forEach(value => {
const pag = value.split(',')
const mid = ((pag.length-1)/2)
console.log(mid, pag[mid])
sum += parseInt(pag[mid]??"");
})
console.log(sum)
})
}
function compareArrays (x: any[], y: any[]): boolean{
return (x.length == y.length && x.every((value, index) => {
return value === y[index];
}))
}

56
src/2024/5/2/index.ts Normal file
View File

@@ -0,0 +1,56 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
const [rawRules, rawPages] = data.split('\n\n')
var rules :Map<string, number> = new Map();
const parsedRules = (rawRules??"").split("\n")
parsedRules.map(pRule => {
const [v1, v2] = pRule.split("|")
rules.set(pRule, -1)
rules.set(`${v2}|${v1}`, 1)
})
let splitPages = (rawPages??"").split("\n")
splitPages = splitPages.filter(value => {
const aPages = value.split(",");
const bPages = value.split(",");
aPages.sort((a, b) => {
return rules.get(`${a}|${b}`)??0
})
return !compareArrays(aPages, bPages);
})
let sortedPages : string[][] = []
splitPages.forEach(value => {
sortedPages.push(value.split(',').sort((a, b) => rules.get(`${a}|${b}`)??0))
})
console.log(sortedPages)
let sum = 0;
sortedPages.forEach(value => {
const mid = ((value.length-1)/2)
console.log(mid, value[mid])
sum += parseInt(value[mid]??"");
})
console.log(sum)
})
}
function compareArrays (x: any[], y: any[]): boolean{
return (x.length == y.length && x.every((value, index) => {
return value === y[index];
}))
}

93
src/2024/6/1/index.ts Normal file
View File

@@ -0,0 +1,93 @@
import fs from 'node:fs';
type Vec2d = {y: number, x: number}
let visited: Map<string, boolean> = new Map<string, boolean>()
let obstacles: boolean[][] = []
let position: Vec2d = {x: -1, y: -1}
let dir_NORTH: Vec2d = {x: 0, y: -1}
let dir_EAST: Vec2d = {x: 1, y: 0 }
let dir_SOUTH: Vec2d = {x: 0, y: 1}
let dir_WEST: Vec2d = {x: -1, y: 0}
let direction: Vec2d = dir_NORTH
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', async (err, data) => {
if (err) throw err;
data.split("\n").forEach((value, index) => {
for (let i = 0; i < value.length; i++) {
if (obstacles[i] === undefined) obstacles[i] = []
if (obstacles[i] === undefined) throw new Error();
// @ts-ignore
obstacles[i][index] = value.charAt(i) === '#'
if (value.charAt(i) === '^') position = {x: i, y: index}
}
})
console.log(position)
console.log(position)
console.log(position)
console.log(position)
console.log(position)
// @ts-ignore
while (position.x>0 && position.y>0 && position.x<obstacles[0].length-1 && position.y<obstacles.length-1){
if (!move()) direction = rotate();
}
let count = visited.size
console.log(visited)
console.log()
console.log()
console.log()
console.log()
console.log(`Visited: ${count}`)
})
}
function move(): boolean {
// @ts-ignore
if (obstacles[position.x+direction.x][position.y+direction.y]){
return false
}
// const oldPos = {x: position.x, y: position.y}
position.x = position.x+direction.x
position.y = position.y+direction.y
// console.log(`move ${positionToString(oldPos)} => ${positionToString(position)}`)
// @ts-ignore
visited.set(JSON.stringify(position), true)
return true
}
function rotate(): { x: number, y: number } {
switch (direction) {
case dir_NORTH:
console.log(`rotate ${positionToString(dir_NORTH)} => ${positionToString(dir_EAST)}`)
return dir_EAST
case dir_EAST:
console.log(`rotate ${positionToString(dir_EAST)} => ${positionToString(dir_SOUTH)}`)
return dir_SOUTH;
case dir_SOUTH:
console.log(`rotate ${positionToString(dir_SOUTH)} => ${positionToString(dir_WEST)}`)
return dir_WEST;
case dir_WEST:
console.log(`rotate ${positionToString(dir_WEST)} => ${positionToString(dir_NORTH)}`)
return dir_NORTH;
}
return dir_NORTH
}
const positionToString = function (a: Vec2d){
return `x: ${a.x} | y:${a.y}`
}

0
src/2024/6/2/index.ts Normal file
View File

27
src/2024/7/1/index.ts Normal file
View File

@@ -0,0 +1,27 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
let sum = 0;
data.split('\n').forEach(line => {
const [result, equators] = line.split(": ")
const factors = (equators??"").split(" ")
if(calculate(parseInt(result??""), factors.map(value => parseInt(value)))) sum += parseInt(result??"")
})
console.log(sum)
})
}
function calculate(result: number, factors: number[]): boolean{
return math(result, factors, 0, 0);
}
function math(result: number, factors: number[], index: number, runningTotal: number): boolean {
if(index === factors.length) return result === runningTotal;
const add = math(result, factors, index+1, runningTotal+(factors[index]??1))
const mult = math(result, factors, index+1, runningTotal*(factors[index]??1))
return add||mult;
}

28
src/2024/7/2/index.ts Normal file
View File

@@ -0,0 +1,28 @@
import fs from 'node:fs';
export default function runner(input: string) {
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
let sum = 0;
data.split('\n').forEach(line => {
const [result, equators] = line.split(": ")
const factors = (equators??"").split(" ")
if(calculate(parseInt(result??""), factors.map(value => parseInt(value)))) sum += parseInt(result??"")
})
console.log(sum)
})
}
function calculate(result: number, factors: number[]): boolean{
return math(result, factors, 0, 0);
}
function math(result: number, factors: number[], index: number, runningTotal: number): boolean {
if(index === factors.length) return result === runningTotal;
const add = math(result, factors, index+1, runningTotal+(factors[index]??1))
const mult = math(result, factors, index+1, runningTotal*(factors[index]??1))
const concat = math(result, factors, index+1, parseInt(runningTotal + "" + (factors[index]??1)))
return add||mult||concat;
}

56
src/2024/8/1/index.ts Normal file
View File

@@ -0,0 +1,56 @@
import fs from 'node:fs';
type Vec2d = {x: number, y: number};
export default function runner(input: string) {
let h: number = 0, w : number = 0
const mapOfMaps: Map<string, Vec2d[]> = new Map();
const listOfAntinodes : Map<string, Vec2d> = new Map()
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
data.split('\n').forEach((line, lineNo) => {
if(h < lineNo) h = lineNo
for (let colNo = 0; colNo < line.length; colNo++) {
if(w<colNo) w = colNo
const char = line.at(colNo)??""
if (char === '.') continue;
if(!mapOfMaps.has(char)) mapOfMaps.set(char, [])
mapOfMaps.get(char)?.push({x: colNo, y: lineNo})
}
})
mapOfMaps.forEach((value) => {
for (let i = 0; i < value.length; i++) {
for (let j = i+1; j < value.length; j++) {
// @ts-ignore
const locDiff: Vec2d = {x: value[i].x - value[j].x, y: value[i].y - value[j].y}
const negLocDiff: Vec2d = negate(locDiff)
// @ts-ignore
const posAntiNode: Vec2d = {x: value[i].x + locDiff.x, y: value[i].y + locDiff.y}
// @ts-ignore
const negAntiNode: Vec2d = {x: value[j].x + negLocDiff.x, y: value[j].y + negLocDiff.y}
addNode(posAntiNode, listOfAntinodes, h, w)
addNode(negAntiNode, listOfAntinodes, h, w)
}
}
})
console.log('Found ' + listOfAntinodes.size + ' antinodes')
})
}
function negate(input : Vec2d){
return {x: input.x*-1, y: input.y*-1}
}
function addNode(node: Vec2d, list: Map<string, Vec2d>, h: number, w: number){
if(node.x <0 || node.x>w || node.y<0 || node.y>h) return false;
if(!list.has(JSON.stringify(node))) list.set(JSON.stringify(node), node)
return true
}

65
src/2024/8/2/index.ts Normal file
View File

@@ -0,0 +1,65 @@
import fs from 'node:fs';
type Vec2d = {x: number, y: number};
export default function runner(input: string) {
let h: number = 0, w : number = 0
const mapOfMaps: Map<string, Vec2d[]> = new Map();
const listOfAntinodes : Map<string, Vec2d> = new Map()
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
data.split('\n').forEach((line, lineNo) => {
if(h < lineNo) h = lineNo
for (let colNo = 0; colNo < line.length; colNo++) {
if(w<colNo) w = colNo
const char = line.at(colNo)??""
if (char === '.') continue;
if(!mapOfMaps.has(char)) mapOfMaps.set(char, [])
mapOfMaps.get(char)?.push({x: colNo, y: lineNo})
}
})
mapOfMaps.forEach((value) => {
for (let i = 0; i < value.length; i++) {
for (let j = i+1; j < value.length; j++) {
// @ts-ignore
calcEcho(value[i], value[j], listOfAntinodes, h, w)
}
}
})
console.log('Found ' + listOfAntinodes.size + ' antinodes')
})
}
function negate(input : Vec2d){
return {x: input.x*-1, y: input.y*-1}
}
function addNode(node: Vec2d, list: Map<string, Vec2d>, h: number, w: number){
if(node.x <0 || node.x>w || node.y<0 || node.y>h) return false;
if(!list.has(JSON.stringify(node))) list.set(JSON.stringify(node), node)
return true
}
function calcEcho(node1: Vec2d, node2: Vec2d, list: Map<string, Vec2d>, h: number, w: number){
const locDiff: Vec2d = {x: node1.x - node2.x, y: node1.y - node2.y}
const negLocDiff: Vec2d = negate(locDiff)
calcEchoRecurse(node1, locDiff, list, h, w)
calcEchoRecurse(node2, locDiff, list, h, w)
calcEchoRecurse(node1, negLocDiff, list, h, w)
calcEchoRecurse(node2, negLocDiff, list, h, w)
}
function calcEchoRecurse(node: Vec2d, vector: Vec2d, list: Map<string, Vec2d>, h: number, w: number){
const loc: Vec2d = {x: node.x + vector.x, y: node.y + vector.y}
if(addNode(loc, list, h, w)) {
calcEchoRecurse(loc,vector, list, h, w)
}
}

39
src/2024/9/1/index.ts Normal file
View File

@@ -0,0 +1,39 @@
import fs from 'node:fs';
export default function runner(input: string) {
const fsblk: number[]= []
let id = 0;
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
for (let i = 0; i < data.length; i++) {
for(let j = 0; j < parseInt(data.charAt(i)); j++) {
if(i%2 == 0){
fsblk.push(id)
} else {
fsblk.push(-1)
}
}
if(i%2 == 0) id++;
}
for (let i = 0; i < fsblk.length; i++) {
while(fsblk[i] === -1) {
fsblk[i] = fsblk.pop()??-1
if(fsblk.length === i+1) {
fsblk.pop()
break
}
}
}
let checksum = 0;
fsblk.forEach((value, index) => {
checksum += value*index
})
console.log(checksum)
})
}

91
src/2024/9/2/index.ts Normal file
View File

@@ -0,0 +1,91 @@
import fs from 'node:fs';
export default function runner(input: string) {
const fsblk: number[]= []
let id = 0;
fs.readFile(`./${input}`, 'utf8', (err, data) => {
if (err) throw err;
for (let i = 0; i < data.length; i++) {
for(let j = 0; j < parseInt(data.charAt(i)); j++) {
if(i%2 == 0){
fsblk.push(id)
} else {
fsblk.push(-1)
}
}
if(i%2 == 0) id++;
}
const spaces: Map<number, number> = new Map()
let currentIndex = 0;
let prevSpace = false;
for (let i = 0; i < fsblk.length; i++) {
if(fsblk[i] === -1) {
if(prevSpace) {
spaces.set(currentIndex, (spaces.get(currentIndex)??0)+1)
} else {
currentIndex = i;
prevSpace = true;
spaces.set(i, 1)
}
} else {
prevSpace = false
}
}
let blocks: Map<number, number> = new Map()
prevSpace = true
for (let i = fsblk.length-1; i > -1; i--) {
if(fsblk[i] !== fsblk[i+1]) prevSpace = true
if(fsblk[i] !== -1) {
if(!prevSpace) {
blocks.set(currentIndex, (blocks.get(currentIndex)??0)+1)
} else {
currentIndex = i;
prevSpace = false;
blocks.set(currentIndex, 1)
}
}
}
console.log(spaces, blocks)
for(let fileId = id; fileId>-1; fileId++) {
const fileIndex = blocks.get(Array.from(blocks.keys())[fileId]??-1)??-1
const fileSize = blocks.get(fileIndex??-1)??-1
const freeBlockIndex = Array.from(spaces.keys())[Array.from(spaces.values()).findIndex(freeSpaceSize => freeSpaceSize>fileSize)]??-1
if(freeBlockIndex === -1) continue
console.log(freeBlockIndex)
console.log(fsblk)
for (let i = freeBlockIndex; i < freeBlockIndex + fileSize; i++) {
fsblk[i] = fileId
}
const newSpace = (spaces.get(freeBlockIndex)??0)-fileSize
spaces.delete(freeBlockIndex)
if(newSpace > 0) spaces.set(freeBlockIndex+fileSize, newSpace)
for (let i = 0; i < fileSize; i++) {
fsblk[fileIndex-1+i] = -1
}
}
let checksum = 0;
fsblk.forEach((value, index) => {
if(value === -1) return
checksum += value*index
})
console.log(checksum)
})
}