Skip to content

Commit

Permalink
Solve day 9
Browse files Browse the repository at this point in the history
  • Loading branch information
Dlurak committed Dec 9, 2024
1 parent 3c03d71 commit f49fa5e
Show file tree
Hide file tree
Showing 16 changed files with 241 additions and 22 deletions.
3 changes: 2 additions & 1 deletion 2024/day04/part2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
setValueAtCoords,
valueAtCoord,
isInBounds,
showVisualization,
} from '@helper';
import { DIAGONAL_OFFSETS } from '@constants';

Expand Down Expand Up @@ -53,7 +54,7 @@ const crossA = allACoords.filter(({ row, col }) => {
return existsMultipleTimes;
});

if (Bun.env.DATA === 'debug') {
if (showVisualization()) {
const aMatrix = setValueAtCoords(
newMatrix({ rows: matrix.length, cols: matrix[0].length }, '.'),
crossA,
Expand Down
3 changes: 2 additions & 1 deletion 2024/day06/part1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
uniqueBy,
setValueAtCord,
print,
showVisualization,
} from '@helper';
import { walk } from './lib';

Expand All @@ -16,7 +17,7 @@ const uniqueCoords = uniqueBy(
([a], [b]) => a.col === b.col && a.row === b.row,
);

if (Bun.env.DATA === 'debug') {
if (showVisualization()) {
const stringMatrix = uniqueCoords.reduce<string[][]>(
(acc, [coord, dir]) =>
setValueAtCord(
Expand Down
19 changes: 11 additions & 8 deletions 2024/day08/part1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
isInBounds,
uniqueCoords,
valueAtCoord,
showVisualization,
} from '@helper';

const input = await loadData();
Expand Down Expand Up @@ -37,19 +38,21 @@ const antinodes = Object.keys(antennaCoords).flatMap((key) => {
});
});

const allAntinodes = antinodes;
const antinodesInBounds = allAntinodes.filter((coord) => {
return isInBounds(matrix, coord);
});
console.log(uniqueCoords(antinodesInBounds).length);

if (Bun.env.DATA === 'debug') {
if (showVisualization()) {
console.log(
print(
antinodes.reduce((acc, coord) => {
const value = valueAtCoord(matrix, coord);
return value === '.' ? setValueAtCord(acc, coord, '#') : acc;
return value === '.'
? setValueAtCord(acc, coord, '\x1b[1m\x1b[31m#\x1b[0m')
: acc;
}, matrix),
),
);
}

const allAntinodes = antinodes;
const antinodesInBounds = allAntinodes.filter((coord) => {
return isInBounds(matrix, coord);
});
console.log(uniqueCoords(antinodesInBounds).length);
13 changes: 7 additions & 6 deletions 2024/day08/part2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
print,
isInBounds,
uniqueCoords,
valueAtCoord,
valueAtCoord,
showVisualization,
} from '@helper';

const input = await loadData();
Expand Down Expand Up @@ -52,15 +53,15 @@ const allAntinodes = [...Object.values(antennaCoords).flat(), ...antinodes];
const antinodesInBounds = allAntinodes.filter((coord) => {
return isInBounds(matrix, coord);
});
console.log(uniqueCoords(antinodesInBounds).length);

if (Bun.env.DATA === 'debug') {
if (showVisualization()) {
console.log(
print(
antinodes.reduce((acc, coord) => {
const value = valueAtCoord(matrix, coord)
return value === '.' ? setValueAtCord(acc, coord, '#') : acc;
antinodesInBounds.reduce((acc, coord) => {
return setValueAtCord(acc, coord, '\x1b[1m\x1b[31m#\x1b[0m');
}, matrix),
),
);
}

console.log(uniqueCoords(antinodesInBounds).length);
8 changes: 8 additions & 0 deletions 2024/day09/lib.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { sumBy } from "@helper"

export const calcChecksum = (arr: number[]) => {
return sumBy(
arr,
(value, index) => (value ?? 0) * index,
)
}
57 changes: 57 additions & 0 deletions 2024/day09/part1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { loadData, mapToInt, showVisualization } from '@helper';
import { calcChecksum } from './lib';

const input = await loadData();
const parsedSizes = mapToInt(input.split(''));
const files = parsedSizes.flatMap((size, index) => {
return Array.from({ length: size }, () =>
index % 2 ? null : Math.floor(index / 2),
);
});

/* Sadly very very slow :( but at least elegant
const moveNum = (arr: (number | null)[]): number[] => {
const arrCopy = arr.slice();
const nullIndex = arrCopy.findIndex((i) => i === null);
if (nullIndex === -1) {
return arrCopy as number[];
}
arrCopy[nullIndex] = arrCopy.at(-1)!;
return moveNum(arrCopy.slice(0, -1));
};
* */

const moveNum = (arr: (number | null)[]): number[] => {
const result: number[] = [];
let left = 0;
let right = arr.length - 1;

while (left <= right) {
if (arr[left] !== null) {
result.push(arr[left]!);
left++;
continue;
}

while (arr[right] === null && left < right) {
right--;
}

if (left >= right) {
break;
}

result.push(arr[right]!);
right--;
left++;
}

return result;
};

if (showVisualization()) {
console.log(moveNum(files).join(''));
}

console.log(calcChecksum(moveNum(files)));
71 changes: 71 additions & 0 deletions 2024/day09/part2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { loadData, mapToInt, showVisualization } from '@helper';
import { calcChecksum } from './lib';

const input = await loadData();
const parsedSizes = mapToInt(input.split(''));
const files = parsedSizes.map((size, index) => {
const id = index % 2 ? null : Math.floor(index / 2);
return { size, id };
});
/* This is a parser for part1
* eventhough this algorithm is optimized on part 2 it can also solve part 1
* ...double as fast as the designated part 1 algorithm
*
const files = parsedSizes.flatMap((size, index) => {
const id = index % 2 ? null : Math.floor(index / 2);
return Array.from({ length: size }, () => ({ size: 1, id }));
});
*/

type Group = (typeof files)[number];

const moveNum = (array: Group[]) => {
const appendix: Group[] = [];
while (array.length > 0) {
const last = array.pop();
if (!last) {
break;
}

if (last.id === null) {
appendix.push(last);
continue;
}
const nullIndex = array.findIndex(
({ id, size }) => id === null && size >= last.size,
);
if (nullIndex === -1) {
appendix.push(last);
continue;
}

if (array[nullIndex].size !== last.size) {
array.splice(nullIndex + 1, 0, {
size: array[nullIndex].size - last.size,
id: null,
});
}
array[nullIndex] = last;
appendix.push({ id: null, size: last.size });
}

return appendix.reverse();
};

const movedFiles = moveNum(files);

if (showVisualization()) {
console.log(
movedFiles
.map(({ id, size }) => {
const string = id === null ? '.' : `${id}`;
return string.repeat(size);
})
.join('|'),
);
}

const numbers = movedFiles.flatMap(({ id, size }) =>
Array.from({ length: size }, () => id!),
);
console.log(calcChecksum(numbers));
2 changes: 1 addition & 1 deletion helpers/deepEqual.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ export function deepEqual(a: unknown, b: unknown): boolean {
}

export function containsDeepEqual<T>(arr: T[], searchValue: T) {
return arr.some((item) => deepEqual(item, searchValue));
return arr.some((item) => deepEqual(item, searchValue));
}
6 changes: 3 additions & 3 deletions helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { median, average } from './medianAndAverage';
import { isPrime } from './isPrime';
import { lastElementOfList } from './last';
import { filterOutNaN, filterOut } from './filterOutNan';
import { loadData } from './loadData';
import { replaceMultiple } from './replaceAll';
import { mapValues } from './objectMap';
import { getKeyByValue } from './getKeyByValue';
Expand All @@ -19,6 +18,7 @@ import { findAllIndexes } from './findAllIndexes';
import { findDuplicates } from './findDuplicates';
import { lines } from './lines';
import { words } from './words';
export * from './loadData';
export * from './unique';
export * from './sum';
export * from './isSorted';
Expand All @@ -35,13 +35,13 @@ export * from './matrix/utils';
export * from './sort';
export * from './removeIndex';
export * from './deepEqual';
export * from './matrix/fill';
// TODO: Test set value at coord
export * from './matrix/setValueAtCoord';
export * from './commonChars';
export * from './chunkify';

export {
loadData,
mapToInt,
product,
range,
Expand All @@ -67,4 +67,4 @@ export {
lines,
words,
};
export const self = <T>(x: T) => x
export const self = <T>(x: T) => x;
2 changes: 2 additions & 0 deletions helpers/loadData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export const loadData = async () => {
const file = Bun.file(Bun.argv[2]);
return await file.text().then((txt) => txt.slice(0, -1));
};

export const showVisualization = () => Bun.env.VIS === 'true';
44 changes: 44 additions & 0 deletions helpers/matrix/fill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {
Coordinate,
Matrix,
applyOffset,
isInBounds,
setValueAtCord,
valueAtCoord,
} from '@helper';
import { ORTHONAL_OFFSETS } from '@constants';

export const floodFill = <T>(
matrix: Matrix<T>,
coord: Coordinate,
newValue: T,
) => {
if (!isInBounds(matrix, coord)) {
return matrix;
}
const startValue = valueAtCoord(matrix, coord)!;
if (startValue === newValue) {
return matrix;
}

const fill = (
matrix: Matrix<T>,
coord: Coordinate,
): Matrix<T> | undefined => {
if (!isInBounds(matrix, coord)) {
return;
}
if (valueAtCoord(matrix, coord) !== startValue) {
return;
}

return Object.values(ORTHONAL_OFFSETS).reduce(
(acc, offset) => {
return fill(acc, applyOffset(coord, offset)) ?? acc;
},
setValueAtCord(matrix, coord, newValue),
);
};

return fill(matrix, coord);
};
2 changes: 1 addition & 1 deletion helpers/removeIndex.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Removes the element at the specified index from an array without modifying the original array.
*
*
* @param arr - The original array.
* @param index - The index of the element to remove.
* @returns A new array with the specified element removed.
Expand Down
5 changes: 4 additions & 1 deletion helpers/unique.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
export const unique = <T extends unknown>(array: T[]): T[] =>
array.filter((value, index, self) => self.indexOf(value) === index);

export const uniqueBy = <T>(arr: T[], isEqual: (val1: T, val2: T) => boolean): T[] => {
export const uniqueBy = <T>(
arr: T[],
isEqual: (val1: T, val2: T) => boolean,
): T[] => {
return arr.reduce((unique: T[], current: T) => {
const isDuplicate = unique.some((existing) => isEqual(existing, current));
if (!isDuplicate) {
Expand Down
1 change: 1 addition & 0 deletions input/2024/day09.debug
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2333133121414131402
Loading

0 comments on commit f49fa5e

Please sign in to comment.