const fs = require('fs'); const input = fs.readFileSync(__dirname + '/input.txt', 'utf8'); interface MyFile { id: number, addr: number, size: number }; const files: Array = []; let pointer = 0; let id = 0; for (let i = 0; i < input.length; i++) { const size = parseInt(input[i]); if (i % 2 === 0) { files.push({ id, size, addr: pointer }); id++; } pointer += size; } function printDisk() { const disk: Array = []; files.forEach((file) => { for (let i = file.addr; i < file.addr + file.size; i++) { disk[i] = ''+file.id; } }); let diskStr = ''; for (let i = 0; i < disk.length; i++) { diskStr += disk[i] || '.'; } console.log(diskStr); } function getFirstSpace(): null|{ addr: number, size: number, index: number } { for (let i = 0; i < files.length; i++) { const file = files[i]; const nextFile = files[i+1]; if (file && nextFile) { const fileEnd = file.addr + file.size; if (nextFile.addr > fileEnd) { return { addr: fileEnd, size: nextFile.addr - fileEnd, index: i + 1, }; } } } return null; } top: while (true) { const lastFile = files.pop()!; let remainingSize = lastFile.size; while (remainingSize > 0) { const firstFreeSpace = getFirstSpace(); if (!firstFreeSpace || firstFreeSpace.addr >= lastFile.addr) { const secondLastFile = files[files.length - 1]; files.push({ addr: secondLastFile.addr + secondLastFile.size, size: remainingSize, id: lastFile.id, }); break top; } let filePartSize; let remainingFreeSpace; if (remainingSize < firstFreeSpace.size) { filePartSize = remainingSize; remainingFreeSpace = firstFreeSpace.size - remainingSize; } else { filePartSize = firstFreeSpace.size; remainingFreeSpace = 0; } files.splice(firstFreeSpace.index, 0, { addr: firstFreeSpace.addr, id: lastFile.id, size: filePartSize }); remainingSize -= filePartSize; } } let checksum = 0; files.forEach((file) => { for (let i = file.addr; i < file.addr + file.size; i++) { checksum += i * file.id; } }); console.log(checksum);