const fs = require('fs'); const input = fs.readFileSync(__dirname + '/input.txt', 'utf8'); interface MyFile { id: number, addr: number, size: number }; const freeSpaces: Array<{ addr: number, size: number }> = []; const files: Array = []; const reorderedFiles: 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++; } else if (size) { freeSpaces.push({ addr: pointer, size }); } pointer += size; } const finalSpace = { addr: pointer, size: 0 }; if (input.length % 2 !== 0) { freeSpaces.push(finalSpace); } function printDisk() { const disk: Array = []; files.forEach((file) => { for (let i = file.addr; i < file.addr + file.size; i++) { disk[i] = ''+file.id; } }); reorderedFiles.forEach((file) => { for (let i = file.addr; i < file.addr + file.size; i++) { disk[i] = ''+file.id; } }); freeSpaces.forEach((space) => { for (let i = space.addr; i < space.addr + space.size; i++) { disk[i] = '.'; } }); console.log(disk.join('')); } console.log(files); while (true) { const lastFile = files.pop()!; let remainingSize = lastFile.size; console.log(files, lastFile, freeSpaces); while (remainingSize > 0) { const firstFreeSpace = freeSpaces.shift()!; let filePartSize; let remainingFreeSpace; if (remainingSize < firstFreeSpace.size) { filePartSize = remainingSize; remainingFreeSpace = firstFreeSpace.size - remainingSize; } else { filePartSize = firstFreeSpace.size; remainingFreeSpace = 0; } reorderedFiles.push({ addr: firstFreeSpace.addr, id: lastFile.id, size: filePartSize }); finalSpace.size += filePartSize; finalSpace.addr -= filePartSize; remainingSize -= filePartSize; if (remainingFreeSpace) { freeSpaces.unshift({ addr: firstFreeSpace.addr + filePartSize, size: remainingFreeSpace }); } } let i = freeSpaces.length - 2; if (!freeSpaces[i]) { break; } while (freeSpaces[i].addr + freeSpaces[i].size === finalSpace.addr) { finalSpace.addr = freeSpaces[i].addr; finalSpace.size += freeSpaces[i].size; freeSpaces[i] = finalSpace; freeSpaces.pop(); i--; } } let checksum = 0; const allFiles = files.concat(reorderedFiles); allFiles.sort((a, b) => a.addr - b.addr); console.log(allFiles, freeSpaces); allFiles.forEach((file) => { for (let i = file.addr; i < file.addr + file.size; i++) { checksum += i * file.id; } }); console.log(checksum);