Add solution day 9

This commit is contained in:
monoid 2024-12-09 15:17:07 +09:00
parent 48617021fe
commit 1a5797e987
4 changed files with 156 additions and 0 deletions

1
day_9/example.txt Normal file
View File

@ -0,0 +1 @@
2333133121414131402

1
day_9/input.txt Normal file

File diff suppressed because one or more lines are too long

80
day_9/solve_1.ts Normal file
View File

@ -0,0 +1,80 @@
export async function readDiskData(path: string) {
const text = await Deno.readTextFile(path);
return text.trim().split("").map(Number);
}
export type Block = {
id: number;
} | null;
export function translateToBlocks(data: number[]) {
const blocks: Block[] = [];
let idGen = 0;
let empty = false;
for (const num of data) {
if (empty) {
for (let i = 0; i < num; i++) {
blocks.push(null);
}
} else {
const id = idGen++;
for (let i = 0; i < num; i++) {
blocks.push({ id });
}
}
empty = !empty;
}
return blocks;
}
export function compressBlocks(blocks: Block[]) {
let left = 0;
let right = blocks.length - 1;
while (left < right) {
// advance left if it's empty
if (blocks[left] !== null) {
left++;
continue;
}
// advance right if it's not empty
if (blocks[right] === null) {
right--;
continue;
}
// swap left and right
blocks[left] = blocks[right];
blocks[right] = null;
left++;
}
return blocks;
}
export function displayBlocks(blocks: Block[]) {
const strs = [];
for (const block of blocks) {
if (block === null) {
strs.push(".");
} else {
strs.push(block.id);
}
}
console.log(strs.join(""));
}
if (import.meta.main) {
const data = await readDiskData("input.txt");
const blocks = translateToBlocks(data);
// displayBlocks(blocks);
compressBlocks(blocks);
// displayBlocks(blocks);
// multiply index and sum
const result = blocks.reduce((acc, block, i) => {
if (block === null) {
return acc;
}
return acc + block.id * i;
}, 0);
console.log(result);
}

74
day_9/solve_2.ts Normal file
View File

@ -0,0 +1,74 @@
import { Block, displayBlocks, readDiskData, translateToBlocks } from "./solve_1.ts";
function newCompressBlocks(blocks: Block[]) {
function findEmptySpace(size: number, limit = blocks.length) {
// find empty spaces
let start = -1;
for (let i = 0; i < limit; i++) {
if (blocks[i] === null) {
if (start === -1) {
start = i;
}
} else {
if (start !== -1) {
if (i - start >= size) {
return start;
}
start = -1;
}
}
}
return -1;
}
// compress blocks
let right = blocks.length - 1;
while (right > 0) {
if (blocks[right] === null) {
right--;
continue;
}
// get the size of the block
let size = 1;
let id = blocks[right]!.id;
for (let i = right - 1; i >= 0; i--) {
if (blocks[i] === null || blocks[i]!.id !== id) {
break;
}
size++;
}
// find empty space
const start = findEmptySpace(size, right);
// console.log("Moved block", start, size, id);
if (start === -1) {
// no empty space found
right = right - size;
continue;
}
// move block
for (let i = 0; i < size; i++) {
blocks[start + i] = blocks[right - i];
blocks[right - i] = null;
}
right = right - size;
}
return blocks;
}
if (import.meta.main) {
const data = await readDiskData("input.txt");
const blocks = translateToBlocks(data);
displayBlocks(blocks);
newCompressBlocks(blocks);
displayBlocks(blocks);
// multiply index and sum
const result = blocks.reduce((acc, block, i) => {
if (block === null) {
return acc;
}
return acc + block.id * i;
}, 0);
console.log(result);
}