@alexaegis/advent-of-code-lib
Version:
Advent of Code Library
853 lines (852 loc) • 15.1 kB
JavaScript
import { az as Vec2, C as max, ay as BoundingBox } from "./array.polyfill-r5d1OMxR.js";
import { NEWLINE } from "./regex.js";
import "@alexaegis/common";
import "js-sdsl";
import "./index-41yGvuWH.js";
import "./map.js";
import "node:perf_hooks";
import "node:fs/promises";
import "node:path";
import "node:fs";
import "kolorist";
import "./set.js";
const is = (...a) => (b) => a.includes(b);
const chunksOfArray = (arr, size) => {
const matrix = [];
for (let i = 0; i < arr.length; i += size) {
matrix.push(arr.slice(i, i + size));
}
return matrix;
};
const copyMatrix = (matrix) => matrix.map((row) => [...row]);
const findCorners = (vectors) => {
let minX = Number.POSITIVE_INFINITY;
let minY = Number.POSITIVE_INFINITY;
let maxX = Number.NEGATIVE_INFINITY;
let maxY = Number.NEGATIVE_INFINITY;
for (const vector of vectors) {
if (vector.x < minX) {
minX = vector.x;
}
if (vector.x > maxX) {
maxX = vector.x;
}
if (vector.y < minY) {
minY = vector.y;
}
if (vector.y > maxY) {
maxY = vector.y;
}
}
return {
topLeft: new Vec2(minX, maxY),
topRight: new Vec2(maxX, maxY),
bottomLeft: new Vec2(minX, minY),
bottomRight: new Vec2(maxX, minY)
};
};
const generateStringTile = (width, height, base = "_") => (base.repeat(width) + "\n").repeat(height);
const createTileMatrixFromMap = (tileMap, tileToString = (t) => t.toString?.() ?? "_", emptyTileBase = "_") => {
const result = [];
const corners = findCorners([...tileMap.keys()].map((c) => new Vec2(c)));
const emptyTiles = [];
let tileWidth = 0;
let tileHeight = 0;
for (let y = 0; y <= corners.topRight.y - corners.bottomLeft.y; y++) {
for (let x = 0; x <= corners.topRight.x - corners.bottomLeft.x; x++) {
const originalVector = new Vec2(x + corners.bottomLeft.x, y + corners.bottomLeft.y);
const tile = tileMap.get(originalVector.toString());
if (tile) {
let row = result[y];
if (!row) {
row = [];
result[y] = row;
}
const s = tileToString(tile);
row[x] = s;
if (tileHeight === 0) {
const tileRows = s.split(NEWLINE);
tileHeight = tileRows.length - 1;
tileWidth = tileRows[0]?.length ?? 0;
}
} else {
emptyTiles.push(new Vec2(x, y));
}
}
}
for (const emptyTile of emptyTiles) {
const row = result[emptyTile.y];
if (row) {
row[emptyTile.x] = generateStringTile(tileWidth, tileHeight, emptyTileBase);
}
}
return result.reverse();
};
function integerLength(n) {
return Math.floor(Math.abs(n)).toString().length;
}
function integerLengthMath(n) {
return Math.ceil(Math.log10(Math.abs(n) + 1));
}
const iteratorGetUntil = (iterator, condition) => {
for (let next = iterator.next(); !next.done; next = iterator.next()) {
if (condition(next.value)) {
return next.value;
}
}
return void 0;
};
const mergeTileMatrix = (tileMatrix, separation = false) => {
const result = [];
for (const tileRow of tileMatrix) {
const rowsOfTiles = tileRow.map((rb) => rb.toString().trim().split(NEWLINE));
const tileHeight = (rowsOfTiles[0]?.length ?? 0) - 1;
for (let i = 0; i <= tileHeight; i++) {
result.push(rowsOfTiles.map((rb) => rb[i]).join(separation ? " " : ""));
}
if (separation) {
result.push("".repeat(result.at(-1)?.length ?? 0));
}
}
return result.join("\n") + "\n";
};
function numAt(n, p) {
return Number.parseInt(n.toString()[p] ?? "0", 10);
}
function numStart(n, length = 1) {
const l = Math.pow(10, Math.floor(Math.log10(n)) - length + 1);
const b = Math.floor(n / l);
const p = Math.pow(10, length);
return b - Math.floor(b / p) * p;
}
const drawMapStatic = (map, renderTile, startY, endY, startX, endX, flip = false, numbered = false) => {
const res = [];
if (numbered) {
res.push(
[...Array.from({ length: endX - startX + 1 }).keys()].map((i) => i + startX).map((i) => i >= 10 ? i.toString() : "0" + i.toString())
);
}
for (let i = startY; i <= endY; i++) {
const row = numbered ? [i >= 10 ? i.toString() : "0" + i.toString()] : [];
for (let j = startX; j <= endX; j++) {
row.push(renderTile(map.get(new Vec2(flip ? i : j, flip ? j : i).toString())));
}
res.push(row);
}
return res;
};
const getMatrixAlphabet = (letterMatrixType) => {
return letterMatrixType === "small" ? MATRIX_ALPHABET_SMALL : MATRIX_ALPHABET_BIG;
};
const getRowRenderedAlphabet = (letterMatrixType) => {
return Object.fromEntries(
Object.entries(getMatrixAlphabet(letterMatrixType)).map(([key, value]) => [
key,
value.split(NEWLINE)
])
);
};
const UPPERCASE_ALPHABET = [
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z"
];
const A_LETTER_SMALL = `.##.
#..#
#..#
####
#..#
#..#`;
const B_LETTER_SMALL = `###.
#..#
###.
#..#
#..#
###.`;
const C_LETTER_SMALL = `.##.
#..#
#...
#...
#..#
.##.`;
const D_UNVERIFIED_LETTER_SMALL = `###.
#..#
#..#
#..#
#..#
###.`;
const E_LETTER_SMALL = `####
#...
###.
#...
#...
####`;
const F_LETTER_SMALL = `####
#...
###.
#...
#...
#...`;
const G_LETTER_SMALL = `.##.
#..#
#...
#.##
#..#
.###`;
const H_LETTER_SMALL = `#..#
#..#
####
#..#
#..#
#..#`;
const I_LETTER_SMALL = `###
.#.
.#.
.#.
.#.
###`;
const J_LETTER_SMALL = `..##
...#
...#
...#
#..#
.##.`;
const K_LETTER_SMALL = `#..#
#.#.
##..
#.#.
#.#.
#..#`;
const L_LETTER_SMALL = `#...
#...
#...
#...
#...
####`;
const M_UNVERIFIED_LETTER_SMALL = `#...#
##.##
#.#.#
#...#
#...#
#...#`;
const N_UNVERIFIED_LETTER_SMALL = `#...#
##..#
#.#.#
#.#.#
#..##
#...#`;
const O_LETTER_SMALL = `.##.
#..#
#..#
#..#
#..#
.##.`;
const P_LETTER_SMALL = `###.
#..#
#..#
###.
#...
#...`;
const Q_UNVERIFIED_LETTER_SMALL = `.##.
#..#
#..#
#..#
#.##
.###`;
const R_LETTER_SMALL = `###.
#..#
#..#
###.
#.#.
#..#`;
const S_LETTER_SMALL = `.###
#...
#...
.##.
...#
###.`;
const T_UNVERIFIED_LETTER_SMALL = `#####
..#..
..#..
..#..
..#..
..#..`;
const U_LETTER_SMALL = `#..#
#..#
#..#
#..#
#..#
.##.`;
const V_UNVERIFIED_LETTER_SMALL = `#...#
#...#
#...#
#...#
.#.#.
..#..`;
const W_UNVERIFIED_LETTER_SMALL = `#.......#
#.......#
#...#...#
#...#...#
.#.#.#.#.
..#...#..`;
const X_UNVERIFIED_LETTER_SMALL = `#...#
.#.#.
..#..
..#..
.#.#.
#...#`;
const Y_LETTER_SMALL = `#...#
#...#
.#.#.
..#..
..#..
..#..`;
const Z_LETTER_SMALL = `####
...#
..#.
.#..
#...
####`;
const MATRIX_ALPHABET_SMALL = {
A: A_LETTER_SMALL,
B: B_LETTER_SMALL,
C: C_LETTER_SMALL,
D: D_UNVERIFIED_LETTER_SMALL,
E: E_LETTER_SMALL,
F: F_LETTER_SMALL,
G: G_LETTER_SMALL,
H: H_LETTER_SMALL,
I: I_LETTER_SMALL,
J: J_LETTER_SMALL,
K: K_LETTER_SMALL,
L: L_LETTER_SMALL,
M: M_UNVERIFIED_LETTER_SMALL,
N: N_UNVERIFIED_LETTER_SMALL,
O: O_LETTER_SMALL,
P: P_LETTER_SMALL,
Q: Q_UNVERIFIED_LETTER_SMALL,
R: R_LETTER_SMALL,
S: S_LETTER_SMALL,
T: T_UNVERIFIED_LETTER_SMALL,
U: U_LETTER_SMALL,
V: V_UNVERIFIED_LETTER_SMALL,
W: W_UNVERIFIED_LETTER_SMALL,
X: X_UNVERIFIED_LETTER_SMALL,
Y: Y_LETTER_SMALL,
Z: Z_LETTER_SMALL
};
const A_LETTER_BIG = `..##..
.#..#.
#....#
#....#
#....#
######
#....#
#....#
#....#
#....#
`;
const B_LETTER_BIG = `#####.
#....#
#....#
#....#
#####.
#....#
#....#
#....#
#....#
#####.
`;
const C_LETTER_BIG = `.####.
#....#
#.....
#.....
#.....
#.....
#.....
#.....
#....#
.####.
`;
const D_UNVERIFIED_LETTER_BIG = `#####.
#....#
#....#
#....#
#....#
#....#
#....#
#....#
#....#
#####.
`;
const E_LETTER_BIG = `######
#.....
#.....
#.....
#####.
#.....
#.....
#.....
#.....
######
`;
const F_LETTER_BIG = `######
#.....
#.....
#.....
#####.
#.....
#.....
#.....
#.....
#.....
`;
const G_LETTER_BIG = `.####.
#....#
#.....
#.....
#.....
#..###
#....#
#....#
#...##
.###.#
`;
const H_LETTER_BIG = `#....#
#....#
#....#
#....#
######
#....#
#....#
#....#
#....#
#....#
`;
const I_UNVERIFIED_LETTER_BIG = `###
.#.
.#.
.#.
.#.
.#.
.#.
.#.
.#.
###
`;
const J_LETTER_BIG = `...###
....#.
....#.
....#.
....#.
....#.
....#.
#...#.
#...#.
.###..
`;
const K_LETTER_BIG = `#....#
#...#.
#..#..
#.#...
##....
##....
#.#...
#..#..
#...#.
#....#
`;
const L_LETTER_BIG = `#.....
#.....
#.....
#.....
#.....
#.....
#.....
#.....
#.....
######
`;
const M_UNVERIFIED_LETTER_BIG = `#.....#
##...##
##...##
#.#.#.#
#.#.#.#
#..#..#
#..#..#
#.....#
#.....#
#.....#
`;
const N_LETTER_BIG = `#....#
##...#
##...#
#.#..#
#.#..#
#..#.#
#..#.#
#...##
#...##
#....#
`;
const O_UNVERIFIED_LETTER_BIG = `.####.
#....#
#....#
#....#
#....#
#....#
#....#
#....#
#....#
.####.
`;
const P_LETTER_BIG = `#####.
#....#
#....#
#....#
#####.
#.....
#.....
#.....
#.....
#.....
`;
const Q_UNVERIFIED_LETTER_BIG = `.####.
#....#
#....#
#....#
#....#
#....#
#....#
#..#.#
#...##
.#####
`;
const R_LETTER_BIG = `#####.
#....#
#....#
#....#
#####.
#..#..
#...#.
#...#.
#....#
#....#
`;
const S_UNVERIFIED_LETTER_BIG = `.####.
#.....
#.....
#.....
.####.
.....#
.....#
.....#
.....#
#####.
`;
const T_UNVERIFIED_LETTER_BIG = `#####
..#..
..#..
..#..
..#..
..#..
..#..
..#..
..#..
..#..
`;
const U_UNVERIFIED_LETTER_BIG = `#....#
#....#
#....#
#....#
#....#
#....#
#....#
#....#
#....#
.####.
`;
const V_UNVERIFIED_LETTER_BIG = `#...#
#...#
#...#
#...#
#...#
#...#
#...#
.#.#.
.#.#.
..#..
`;
const W_UNVERIFIED_LETTER_BIG = `#.......#
#.......#
#.......#
#...#...#
#...#...#
#...#...#
#...#...#
.#.#.#.#.
.#.#.#.#.
..#...#..
`;
const X_LETTER_BIG = `#....#
#....#
.#..#.
.#..#.
..##..
..##..
.#..#.
.#..#.
#....#
#....#
`;
const Y_UNVERIFIED_LETTER_BIG = `#...#
#...#
.#.#.
.#.#.
..#..
..#..
..#..
..#..
..#..
..#..
`;
const Z_LETTER_BIG = `######
.....#
.....#
....#.
...#..
..#...
.#....
#.....
#.....
######
`;
const MATRIX_ALPHABET_BIG = {
A: A_LETTER_BIG,
B: B_LETTER_BIG,
C: C_LETTER_BIG,
D: D_UNVERIFIED_LETTER_BIG,
E: E_LETTER_BIG,
F: F_LETTER_BIG,
G: G_LETTER_BIG,
H: H_LETTER_BIG,
I: I_UNVERIFIED_LETTER_BIG,
J: J_LETTER_BIG,
K: K_LETTER_BIG,
L: L_LETTER_BIG,
M: M_UNVERIFIED_LETTER_BIG,
N: N_LETTER_BIG,
O: O_UNVERIFIED_LETTER_BIG,
P: P_LETTER_BIG,
Q: Q_UNVERIFIED_LETTER_BIG,
R: R_LETTER_BIG,
S: S_UNVERIFIED_LETTER_BIG,
T: T_UNVERIFIED_LETTER_BIG,
U: U_UNVERIFIED_LETTER_BIG,
V: V_UNVERIFIED_LETTER_BIG,
W: W_UNVERIFIED_LETTER_BIG,
X: X_LETTER_BIG,
Y: Y_UNVERIFIED_LETTER_BIG,
Z: Z_LETTER_BIG
};
const LETTER_SPACING = 1;
const parseLetterMatrix = (matrix, letterType = "small") => {
const renderedAlphabet = getRowRenderedAlphabet(letterType);
const renderedRows = matrix.map((row) => row.join(""));
const width = renderedRows.map((row) => row.length).reduce(max, Number.NEGATIVE_INFINITY);
const parsedLetters = [];
let offset = 0;
while (offset <= width) {
let someMatched = false;
let matchedWidth = 4;
for (const letter of UPPERCASE_ALPHABET) {
const renderedLetter = renderedAlphabet[letter];
const renderedLetterFirstRow = renderedLetter[0];
if (renderedLetterFirstRow) {
const letterWidth = renderedLetterFirstRow.length;
const matches = renderedRows.every((renderedRow, i) => {
const letterPortion = renderedRow.slice(offset, offset + letterWidth);
return renderedLetter[i] === letterPortion;
});
if (matches) {
parsedLetters.push(letter);
matchedWidth = renderedLetterFirstRow.length;
someMatched = true;
}
}
}
offset += matchedWidth + LETTER_SPACING;
if (offset <= width && !someMatched) {
throw new Error(
`No letter matched at offset ${offset - (matchedWidth + LETTER_SPACING)} during letter matrix parsing!`
);
}
}
return parsedLetters.join("");
};
const pairs = (t) => {
const result = [];
for (let i = 0; i < t.length - 1; i++) {
for (let j = i; j < t.length - 1; j++) {
result.push([t[i], t[j + 1]]);
}
}
return result;
};
const perm = (a) => {
return a.length > 0 ? a.reduce(
(r, v, i) => [
...r,
...perm([...a.slice(0, i), ...a.slice(i + 1)]).map((x) => [v, ...x])
],
[]
) : [[]];
};
const rotateArrayTimes = (array, n) => {
let i = 0;
const na = Math.abs(n);
while (i < na) {
if (n > 0) {
array.push(array.shift());
} else {
array.unshift(array.pop());
}
i++;
}
return array;
};
const rotateArray = (array, until) => {
while (until(array, array[0])) {
array.push(array.shift());
}
return array;
};
const rotateArrayBack = (array, until) => {
while (until(array, array.at(-1))) {
array.unshift(array.pop());
}
return array;
};
const usingMap = (map) => (key) => map[key];
const vectorsToMatrix = (vects) => {
const boundingBox = BoundingBox.fromVectors(vects);
const matrix = [];
for (let y = boundingBox.top; y <= boundingBox.bottom; y++) {
const row = [];
for (let x = boundingBox.left; x <= boundingBox.right; x++) {
if (vects.some((v) => v.x === x && v.y === y)) {
row.push("#");
} else {
row.push(".");
}
}
matrix.push(row);
}
return {
matrix,
boundingBox
};
};
export {
K_LETTER_BIG as $,
A_LETTER_SMALL as A,
B_LETTER_SMALL as B,
C_LETTER_SMALL as C,
D_UNVERIFIED_LETTER_SMALL as D,
E_LETTER_SMALL as E,
F_LETTER_SMALL as F,
G_LETTER_SMALL as G,
H_LETTER_SMALL as H,
I_LETTER_SMALL as I,
J_LETTER_SMALL as J,
K_LETTER_SMALL as K,
L_LETTER_SMALL as L,
M_UNVERIFIED_LETTER_SMALL as M,
N_UNVERIFIED_LETTER_SMALL as N,
O_LETTER_SMALL as O,
P_LETTER_SMALL as P,
Q_UNVERIFIED_LETTER_SMALL as Q,
R_LETTER_SMALL as R,
S_LETTER_SMALL as S,
T_UNVERIFIED_LETTER_SMALL as T,
UPPERCASE_ALPHABET as U,
V_UNVERIFIED_LETTER_SMALL as V,
W_UNVERIFIED_LETTER_SMALL as W,
X_UNVERIFIED_LETTER_SMALL as X,
Y_LETTER_SMALL as Y,
Z_LETTER_SMALL as Z,
J_LETTER_BIG as _,
copyMatrix as a,
L_LETTER_BIG as a0,
M_UNVERIFIED_LETTER_BIG as a1,
N_LETTER_BIG as a2,
O_UNVERIFIED_LETTER_BIG as a3,
P_LETTER_BIG as a4,
Q_UNVERIFIED_LETTER_BIG as a5,
R_LETTER_BIG as a6,
S_UNVERIFIED_LETTER_BIG as a7,
T_UNVERIFIED_LETTER_BIG as a8,
U_UNVERIFIED_LETTER_BIG as a9,
V_UNVERIFIED_LETTER_BIG as aa,
W_UNVERIFIED_LETTER_BIG as ab,
X_LETTER_BIG as ac,
Y_UNVERIFIED_LETTER_BIG as ad,
Z_LETTER_BIG as ae,
MATRIX_ALPHABET_BIG as af,
parseLetterMatrix as ag,
pairs as ah,
perm as ai,
rotateArrayTimes as aj,
rotateArray as ak,
rotateArrayBack as al,
usingMap as am,
vectorsToMatrix as an,
createTileMatrixFromMap as b,
chunksOfArray as c,
integerLength as d,
integerLengthMath as e,
findCorners as f,
generateStringTile as g,
iteratorGetUntil as h,
is as i,
numStart as j,
drawMapStatic as k,
getMatrixAlphabet as l,
mergeTileMatrix as m,
numAt as n,
getRowRenderedAlphabet as o,
U_LETTER_SMALL as p,
MATRIX_ALPHABET_SMALL as q,
A_LETTER_BIG as r,
B_LETTER_BIG as s,
C_LETTER_BIG as t,
D_UNVERIFIED_LETTER_BIG as u,
E_LETTER_BIG as v,
F_LETTER_BIG as w,
G_LETTER_BIG as x,
H_LETTER_BIG as y,
I_UNVERIFIED_LETTER_BIG as z
};