85 lines
2.2 KiB
TypeScript
85 lines
2.2 KiB
TypeScript
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<T>(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;
|
|
} |