Solve 2024-06 (using bruteforce)
This commit is contained in:
@@ -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>
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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));
|
||||
@@ -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();
|
||||
};
|
||||
Reference in New Issue
Block a user