import { CountMap } from "util/count-map";
import { CharColl, Collection2D } from "util/collection";
// If blank strings/ints is not enough
export const inputMapper = (inputs: string) => CharColl(inputs);
function isNumber(char: string | undefined): boolean {
return !!char && char.length === 1 && "1234567890".includes(char);
}
function isSymbol(char: string): boolean {
return char !== "." && !isNumber(char);
}
export function solution1(inputs: Collection2D<string>): number {
const grid = inputs.x.toGrid();
let result = 0;
for (const [y, row] of grid.traverseRows()) {
const iter = row.entries();
for (const [x, char] of iter) {
if (!isNumber(char)) continue;
const threeDigits = row.slice(x, x + 3);
const numLength = threeDigits.countWhile(isNumber);
if (numLength >= 1) {
for (let i = x; i < x + numLength; i++) {
if (grid.adjacent(i, y).some(([val]) => isSymbol(val))) {
const add = threeDigits.slice(0, numLength).join("");
result += parseInt(add);
break;
}
}
// Skip til the end of the number
for (let i = x; i < x + numLength; i++) {
iter.next();
}
}
}
}
return result;
}
export function solution2(inputs: Collection2D<string>): number {
const grid = inputs.x.toGrid();
const gears = new Map<string, number>();
const counter = new CountMap<string>();
for (const [y, row] of grid.traverseRows()) {
const iter = row.entries();
for (const [x, char] of iter) {
if (!isNumber(char)) continue;
const threeDigits = row.slice(x, x + 3);
const numLength = threeDigits.countWhile(isNumber);
if (numLength >= 1) {
for (let i = x; i < x + numLength; i++) {
const gear = grid.adjacent(i, y).find(([val]) => val === "*");
if (gear) {
const [_, gx, gy] = gear;
const add = Number(threeDigits.slice(0, numLength).join(""));
const gearName = `${gx},${gy}`;
gears.set(gearName, (gears.get(gearName) ?? 1) * add);
counter.add(gearName);
break;
}
}
// Skip til the end of the number
for (let i = x; i < x + numLength; i++) {
iter.next();
}
}
}
}
let result = 0;
for (const [gear, count] of counter.entries()) {
if (count === 2) {
result += gears.get(gear) ?? 0;
}
}
return result;
}