From 8b9c5f91fe6c42d17f717403acf1d0351c6d8950 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 11 Dec 2024 12:20:05 +0000 Subject: [PATCH] Day 9 --- 2024/09/index.ts | 85 +++++++++++++++++++++-------------------------- 2024/09/index2.ts | 71 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 48 deletions(-) create mode 100644 2024/09/index2.ts diff --git a/2024/09/index.ts b/2024/09/index.ts index 24fa715..e1ecf2b 100644 --- a/2024/09/index.ts +++ b/2024/09/index.ts @@ -4,9 +4,7 @@ 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; @@ -16,18 +14,10 @@ for (let i = 0; i < input.length; 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) => { @@ -35,28 +25,48 @@ function printDisk() { 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('')); + 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; } -console.log(files); +top: while (true) { const lastFile = files.pop()!; let remainingSize = lastFile.size; - console.log(files, lastFile, freeSpaces); while (remainingSize > 0) { - const firstFreeSpace = freeSpaces.shift()!; + 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) { @@ -66,38 +76,17 @@ while (true) { filePartSize = firstFreeSpace.size; remainingFreeSpace = 0; } - reorderedFiles.push({ addr: firstFreeSpace.addr, id: lastFile.id, size: filePartSize }); - finalSpace.size += filePartSize; - finalSpace.addr -= filePartSize; + files.splice(firstFreeSpace.index, 0, { addr: firstFreeSpace.addr, id: lastFile.id, size: 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) => { +files.forEach((file) => { for (let i = file.addr; i < file.addr + file.size; i++) { checksum += i * file.id; } }); -console.log(checksum); \ No newline at end of file +console.log(checksum); diff --git a/2024/09/index2.ts b/2024/09/index2.ts new file mode 100644 index 0000000..b7e30f8 --- /dev/null +++ b/2024/09/index2.ts @@ -0,0 +1,71 @@ +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(size: number): 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 >= size) { + return { + addr: fileEnd, + size: nextFile.addr - fileEnd, + index: i + 1, + }; + } + } + } + return null; +} + +files.slice().reverse().forEach((lastFile, i) => { + const firstFreeSpace = getFirstSpace(lastFile.size); + if (!firstFreeSpace || firstFreeSpace.addr >= lastFile.addr) { + return; + } + files.splice(files.indexOf(lastFile), 1); + files.splice(firstFreeSpace.index, 0, { addr: firstFreeSpace.addr, id: lastFile.id, size: lastFile.size }); +}); + +let checksum = 0; + +files.forEach((file) => { + for (let i = file.addr; i < file.addr + file.size; i++) { + checksum += i * file.id; + } +}); + +console.log(checksum);