Solve 2024-14
This commit is contained in:
@@ -176,4 +176,5 @@ dist
|
|||||||
|
|
||||||
|
|
||||||
input.txt
|
input.txt
|
||||||
|
input.js
|
||||||
!template/input.txt
|
!template/input.txt
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="2024-14" type="BunRunConfiguration">
|
||||||
|
<option name="program" value="2024/14/run.ts" />
|
||||||
|
<option name="workingDirectory" value="$PROJECT_DIR$" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
const xMax = 11;
|
||||||
|
const yMax = 7;
|
||||||
|
|
||||||
|
const input = `p=0,4 v=3,-3
|
||||||
|
p=6,3 v=-1,-3
|
||||||
|
p=10,3 v=-1,2
|
||||||
|
p=2,0 v=2,-1
|
||||||
|
p=0,0 v=1,3
|
||||||
|
p=3,0 v=-2,-2
|
||||||
|
p=7,6 v=-1,-3
|
||||||
|
p=3,0 v=-1,-2
|
||||||
|
p=9,3 v=2,3
|
||||||
|
p=7,3 v=-1,2
|
||||||
|
p=2,4 v=2,-3
|
||||||
|
p=9,5 v=-3,-3`;
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { describe, expect, it } from 'bun:test';
|
||||||
|
import { solveFirst } from './index.ts';
|
||||||
|
|
||||||
|
describe('2024-14', () => {
|
||||||
|
const testInput = `p=0,4 v=3,-3
|
||||||
|
p=6,3 v=-1,-3
|
||||||
|
p=10,3 v=-1,2
|
||||||
|
p=2,0 v=2,-1
|
||||||
|
p=0,0 v=1,3
|
||||||
|
p=3,0 v=-2,-2
|
||||||
|
p=7,6 v=-1,-3
|
||||||
|
p=3,0 v=-1,-2
|
||||||
|
p=9,3 v=2,3
|
||||||
|
p=7,3 v=-1,2
|
||||||
|
p=2,4 v=2,-3
|
||||||
|
p=9,5 v=-3,-3`;
|
||||||
|
it('first', () => {
|
||||||
|
expect(solveFirst(`p=2,4 v=2,-3`, 11, 7, 0)).toBe(0);
|
||||||
|
expect(solveFirst(testInput, 11, 7)).toBe(12);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
import { multArray } from '../../utils/array.ts';
|
||||||
|
import {
|
||||||
|
calculateVariance,
|
||||||
|
type Coordinate,
|
||||||
|
CoordinateIndices,
|
||||||
|
type Coordinates,
|
||||||
|
type CoordinateSides,
|
||||||
|
isCoordinateEqual
|
||||||
|
} from '../../utils/coordinates.ts';
|
||||||
|
|
||||||
|
function mod(x: number, m: number) {
|
||||||
|
return ((x % m) + m) % m;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function solveFirst(
|
||||||
|
input: string,
|
||||||
|
xMax = 101,
|
||||||
|
yMax = 103,
|
||||||
|
iterations = 100
|
||||||
|
): number {
|
||||||
|
const match = input.matchAll(/^p=(-?\d*),(-?\d*) v=(-?\d*),(-?\d*)$/gm);
|
||||||
|
|
||||||
|
const matches = Array.from(match, (m) => ({
|
||||||
|
p: m.slice(1, 3).map(Number) as Coordinate,
|
||||||
|
v: m.slice(3, 5).map(Number) as Coordinate
|
||||||
|
}));
|
||||||
|
|
||||||
|
const finalPositions = matches.map(
|
||||||
|
(p) =>
|
||||||
|
[
|
||||||
|
mod(p.p[0] + p.v[0] * iterations, xMax),
|
||||||
|
mod(p.p[1] + p.v[1] * iterations, yMax)
|
||||||
|
] as Coordinate
|
||||||
|
);
|
||||||
|
|
||||||
|
const centerX = Math.floor(xMax / 2);
|
||||||
|
const centerY = Math.floor(yMax / 2);
|
||||||
|
|
||||||
|
const sumQuadrants = finalPositions.reduce(
|
||||||
|
(quads, position) => {
|
||||||
|
const [x, y] = position;
|
||||||
|
if (x < centerX) {
|
||||||
|
if (y < centerY) {
|
||||||
|
quads[0]++;
|
||||||
|
} else if (y > centerY) {
|
||||||
|
quads[3]++;
|
||||||
|
}
|
||||||
|
} else if (x > centerX) {
|
||||||
|
if (y < centerY) {
|
||||||
|
quads[1]++;
|
||||||
|
} else if (y > centerY) {
|
||||||
|
quads[2]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return quads;
|
||||||
|
},
|
||||||
|
[0, 0, 0, 0]
|
||||||
|
);
|
||||||
|
|
||||||
|
return multArray(sumQuadrants);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function solveSecond(input: string, xMax = 101, yMax = 103): number {
|
||||||
|
const match = input.matchAll(/^p=(-?\d*),(-?\d*) v=(-?\d*),(-?\d*)$/gm);
|
||||||
|
|
||||||
|
const matches = Array.from(match, (m) => ({
|
||||||
|
p: m.slice(1, 3).map(Number) as Coordinate,
|
||||||
|
v: m.slice(3, 5).map(Number) as Coordinate
|
||||||
|
}));
|
||||||
|
|
||||||
|
for (let i = 0; i < xMax * yMax; i++) {
|
||||||
|
const finalPositions = matches.map(
|
||||||
|
(p) =>
|
||||||
|
[
|
||||||
|
mod(p.p[0] + p.v[0] * i, xMax),
|
||||||
|
mod(p.p[1] + p.v[1] * i, yMax)
|
||||||
|
] as Coordinate
|
||||||
|
);
|
||||||
|
const oX = calculateVariance(finalPositions, CoordinateIndices.x);
|
||||||
|
|
||||||
|
const oY = calculateVariance(finalPositions, CoordinateIndices.y);
|
||||||
|
calculateVariance([[0, 1, 2]] as CoordinateSides, CoordinateIndices.side);
|
||||||
|
|
||||||
|
// hard coded, ups
|
||||||
|
// would be better to find the lowest oX = lX in 0-maxX and lowest oY = lY in 0-maxY
|
||||||
|
// then solve yMax * n + lY = xMax * (n+1) + lX, for n
|
||||||
|
// IDK why x+1 tho
|
||||||
|
if (oX < 600 && oY < 600) {
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
console.log(i, oX.toFixed(0), oY.toFixed(0));
|
||||||
|
renderRobots(finalPositions, xMax, yMax);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderRobots(coords: Coordinates, xMax: number, yMax: number) {
|
||||||
|
for (let y = 0; y < yMax; y++) {
|
||||||
|
const row = new Array(xMax)
|
||||||
|
.fill(' ')
|
||||||
|
.map((_, x) =>
|
||||||
|
coords.some((c) => isCoordinateEqual(c, [x, y])) ? '*' : ' '
|
||||||
|
);
|
||||||
|
console.log(row.join(''));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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,99 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>AOC 2024-14 Part 2</title>
|
||||||
|
<style>
|
||||||
|
#main {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(101, 5px);
|
||||||
|
}
|
||||||
|
#main > div {
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
}
|
||||||
|
.black {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="main"></div>
|
||||||
|
<button id="step">+1</button>
|
||||||
|
<button id="step2">+x</button>
|
||||||
|
<button id="step3">+y</button>
|
||||||
|
<input id="iteration" type="number" value="0" size="1" min="0" />
|
||||||
|
</body>
|
||||||
|
<script src="./input.js"></script>
|
||||||
|
<!-- <script src="./example-input.js"></script>-->
|
||||||
|
<script>
|
||||||
|
const main = document.getElementById('main');
|
||||||
|
main.style.gridTemplateColumns = `repeat(${xMax}, 5px)`;
|
||||||
|
const iteration = document.getElementById('iteration');
|
||||||
|
const stepBtn = document.getElementById('step');
|
||||||
|
const step2Btn = document.getElementById('step2');
|
||||||
|
step2Btn.innerText = `+x (${xMax})`;
|
||||||
|
const step3Btn = document.getElementById('step3');
|
||||||
|
step3Btn.innerText = `+y (${yMax})`;
|
||||||
|
|
||||||
|
const pixels = [];
|
||||||
|
for (let i = 0; i < xMax * yMax; i++) {
|
||||||
|
const pixel = document.createElement('div');
|
||||||
|
pixels.push(pixel);
|
||||||
|
main.appendChild(pixel);
|
||||||
|
}
|
||||||
|
let step = 0;
|
||||||
|
|
||||||
|
const match = input.matchAll(/^p=(-?\d*),(-?\d*) v=(-?\d*),(-?\d*)$/gm);
|
||||||
|
|
||||||
|
const matches = Array.from(match, (m) => ({
|
||||||
|
p: m.slice(1, 3).map(Number),
|
||||||
|
v: m.slice(3, 5).map(Number)
|
||||||
|
}));
|
||||||
|
|
||||||
|
function mod(x, m) {
|
||||||
|
return ((x % m) + m) % m;
|
||||||
|
}
|
||||||
|
console.log(matches);
|
||||||
|
|
||||||
|
stepBtn.addEventListener('click', () => {
|
||||||
|
step++;
|
||||||
|
render();
|
||||||
|
});
|
||||||
|
step2Btn.addEventListener('click', () => {
|
||||||
|
step += xMax;
|
||||||
|
render();
|
||||||
|
});
|
||||||
|
step3Btn.addEventListener('click', () => {
|
||||||
|
step += yMax;
|
||||||
|
render();
|
||||||
|
});
|
||||||
|
iteration.addEventListener('input', () => {
|
||||||
|
step = parseInt(iteration.value);
|
||||||
|
render();
|
||||||
|
});
|
||||||
|
|
||||||
|
render();
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
iteration.value = step.toString();
|
||||||
|
|
||||||
|
const finalPositions = matches.map((p) => [
|
||||||
|
mod(p.p[0] + p.v[0] * step, xMax),
|
||||||
|
mod(p.p[1] + p.v[1] * step, yMax)
|
||||||
|
]);
|
||||||
|
|
||||||
|
for (let y = 0; y < yMax; y++) {
|
||||||
|
for (let x = 0; x < xMax; x++) {
|
||||||
|
const pixel = pixels[y * xMax + x];
|
||||||
|
|
||||||
|
if (finalPositions.some((c) => c[0] === x && c[1] === y)) {
|
||||||
|
pixel.classList.add('black');
|
||||||
|
} else {
|
||||||
|
pixel.classList.remove('black');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user