Solve 2024-06 (using bruteforce)

This commit is contained in:
2024-12-06 21:05:01 +01:00
parent 8e8012e8a5
commit 62baa825f2
8 changed files with 220 additions and 1 deletions
+7
View File
@@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="2024-06" type="BunRunConfiguration">
<option name="program" value="2024/06/run.ts" />
<option name="workingDirectory" value="$PROJECT_DIR$" />
<method v="2" />
</configuration>
</component>
+22
View File
@@ -0,0 +1,22 @@
import { describe, expect, it } from 'bun:test';
import { solveFirst } from './index.ts';
describe('2024-06', () => {
const testInput = `....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...`;
it('first', () => {
expect(solveFirst(testInput)).toBe(41);
});
it('second', () => {
// that takes too long
// expect(solveSecond(testInput)).toBe(6);
});
});
+127
View File
@@ -0,0 +1,127 @@
import { sumBy } from '../../utils/array.ts';
export function replace(arr: string[], x: number, y: number, char: string) {
arr[y] = arr[y].substring(0, x) + char + arr[y].substring(x + 1);
}
const directions = [
{ d: '^', x: 0, y: -1 },
{ d: '>', x: 1, y: 0 },
{ d: 'v', x: 0, y: 1 },
{ d: '<', x: -1, y: 0 }
] as const;
export function solveFirst(input: string): number {
const rows = input.split('\n');
const columnCount = rows[0].length;
const rowCount = rows.length;
let y = rows.findIndex((r) => r.indexOf('^') >= 0);
let x = rows[y].indexOf('^');
let direction = 0;
while (x >= 0 && x < columnCount && y >= 0 && y < rowCount) {
const nextX = x + directions[direction].x;
const nextY = y + directions[direction].y;
if (rows[nextY]?.[nextX] === '#') {
direction = (direction + 1) % 4;
}
replace(rows, x, y, 'X');
x += directions[direction].x;
y += directions[direction].y;
}
return sumBy(rows, (r) => [...r.matchAll(/X/g)].length);
}
export function getNextObstacle(
rows: string[],
startX: number,
startY: number,
d: number
): false | { x: number; y: number } {
let x = startX;
let y = startY;
while (true) {
const nextX = x + directions[d].x;
const nextY = y + directions[d].y;
const next = rows[nextY]?.[nextX];
if (!next) {
return false;
}
if (next === '#') {
return { x, y };
}
x = nextX;
y = nextY;
}
}
export function finishes(
rows: string[],
startX: number,
startY: number,
d: number
): boolean {
let x = startX;
let y = startY;
let i = 0;
do {
const next = getNextObstacle(rows, x, y, (d + i) % 4);
if (!next) {
return true;
}
x = next.x;
y = next.y;
i++;
// TODO: be smarter
} while (i < 1_000_000);
return false;
}
export function solveRow(
rows: string[],
row: number,
startX: number,
startY: number,
startDirection: number
) {
let found = 0;
for (let column = 0; column < rows[0].length; column++) {
if ((row === startX && column === startY) || rows[row][column] === '#') {
continue;
}
replace(rows, column, row, '#');
if (!finishes(rows, startX, startY, startDirection)) {
found++;
}
replace(rows, column, row, '.');
}
return found;
}
export function solveSecond(input: string): number {
const rows = input.split('\n');
const rowCount = rows.length;
const y = rows.findIndex((r) => r.indexOf('^') >= 0);
const x = rows[y].indexOf('^');
const direction = 0;
let found = 0;
for (let row = 0; row < rowCount; row++) {
found += solveRow(rows, row, x, y, direction);
console.log('row:', row, 'found', found);
}
return found;
}
+12
View File
@@ -0,0 +1,12 @@
import { join } from 'path';
import { solveFirst, solveSecond } from './index.ts';
const input = await Bun.file(join(__dirname, 'input.txt')).text();
const firstAnswer = solveFirst(input);
console.log(firstAnswer);
const secondAnswer = solveSecond(input);
console.log(secondAnswer);
+29
View File
@@ -0,0 +1,29 @@
import { availableParallelism } from 'os';
import pLimit from 'p-limit';
import { join } from 'path';
import { sumArray } from '../../utils/array.ts';
const workerFile = new URL('worker.ts', import.meta.url).href;
const eva = (i: number) =>
new Promise<number>((resolve) => {
const worker = new Worker(workerFile);
worker.postMessage(i);
worker.onmessage = (event) => {
console.log('row:', i, 'found', event.data);
resolve(event.data as number);
};
});
const input = await Bun.file(join(__dirname, 'input.txt')).text();
const rowCount = input.split('\n').length;
const work = new Array(rowCount).fill(0).map((_, i) => i);
const limit = pLimit(availableParallelism());
const solution = await Promise.all(work.map((w) => limit(eva, w)));
console.log(solution);
console.log(sumArray(solution));
+21
View File
@@ -0,0 +1,21 @@
import { join } from 'path';
import { solveRow } from './index.ts';
declare var self: Worker;
const input = await Bun.file(join(__dirname, 'input.txt')).text();
self.onmessage = (event) => {
const row = event.data as number;
console.log('Start row', row);
const rows = input.split('\n');
const y = rows.findIndex((r) => r.indexOf('^') >= 0);
const x = rows[y].indexOf('^');
const direction = 0;
postMessage(solveRow(rows, row, x, y, direction));
process.exit();
};