export type Cell = "#"|"." export type Data = Cell[][] export function isCell(x: string): x is Cell { return x === "#" || x === "."; } export function normalizeCRLF(str: string) { return str.replace(/\r\n/g, "\n"); } export function readData(content: string): Data[]{ const normalized = normalizeCRLF(content); const maps = normalized.split("\n\n"); return maps.map(x => x.split("\n").map(x => { const cells = x.split(""); if (cells.every(isCell)) { return cells; } throw new Error("Invalid line: " + x); })); } export function transpose(arr: T[][]): T[][] { return arr[0].map((_, i) => arr.map(x => x[i])); } export function getBitsNumbers(cells: Cell[]){ if (cells.length > 30) { throw new Error("Too long line"); } const numbers = cells.map(x => x === "#" ? 1 : 0); let ret = 0; for (let i = 0; i < numbers.length; i++) { ret = ret << 1; ret = ret | numbers[i]; } return ret; } /** * Find the reflection index in the given array. * * @param {number[]} arr - the input array of numbers * @return {number} the reflection index if found, otherwise -1 */ export function getReflectionIndex(arr: number[]): number { for (let i = 1; i < arr.length; i++) { let isEqual = true; for (let j = i; j < arr.length && (2*i - j-1 >= 0) ; j++) { if (arr[j] !== arr[2*i-j-1]) { isEqual = false; break; } } if (isEqual) { return i; } } return -1; } export function popcount(n: number): number{ n = n - ((n >> 1) & 0x55555555); n = (n & 0x33333333) + ((n >> 2) & 0x33333333); return (((n + (n >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; } export function correctReflection(arr: number[]): number { let diff: number; for (let i = 1; i < arr.length; i++) { diff = 0; for (let j = i; j < arr.length && (2*i - j-1 >= 0) ; j++) { diff += popcount(arr[j] ^ arr[2*i-j-1]) // console.log(arr[j], arr[2*i-j-1], diff) if (diff > 1) { break; } } if (diff === 1) { return i; } } return -1; }