import 2024
This commit is contained in:
38
src/2024/1/1/index.ts
Normal file
38
src/2024/1/1/index.ts
Normal 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
37
src/2024/1/2/index.ts
Normal 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
50
src/2024/10/1/index.ts
Normal 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
0
src/2024/10/2/index.ts
Normal file
25
src/2024/11/1/index.ts
Normal file
25
src/2024/11/1/index.ts
Normal 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
40
src/2024/11/2/index.ts
Normal 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
69
src/2024/12/1/index.ts
Normal 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
60
src/2024/16/1/index.ts
Normal 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
46
src/2024/2/1/index.ts
Normal 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
63
src/2024/2/2/index.ts
Normal 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
24
src/2024/3/1/index.ts
Normal 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
27
src/2024/3/2/index.ts
Normal 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
58
src/2024/4/1/index.ts
Normal 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
43
src/2024/4/2/index.ts
Normal 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
52
src/2024/5/1/index.ts
Normal 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
56
src/2024/5/2/index.ts
Normal 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
93
src/2024/6/1/index.ts
Normal 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
0
src/2024/6/2/index.ts
Normal file
27
src/2024/7/1/index.ts
Normal file
27
src/2024/7/1/index.ts
Normal 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
28
src/2024/7/2/index.ts
Normal 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
56
src/2024/8/1/index.ts
Normal 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
65
src/2024/8/2/index.ts
Normal 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
39
src/2024/9/1/index.ts
Normal 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
91
src/2024/9/2/index.ts
Normal 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)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user