function hash(s: string) {
    let ret = 0;
    for (let i = 0; i < s.length; i++) {
        const ch = s.charCodeAt(i);
        ret += ch;
        ret *= 17;
        ret %= 256;
    }
    return ret;
}

type Inst = {
    kind: "remove",
    lens: string
} | {
    kind: "add",
    lens: string,
    /**
     * focal length
     * 1-9
     */
    focal: number,
}

function decodeInst(input: string): Inst {
    if (input.endsWith("-")) {
        return {
            kind: "remove",
            lens: input.slice(0, -1)
        }
    }
    const [lens, focal] = input.split("=");
    return {
        kind: "add",
        lens,
        focal: parseInt(focal)
    }
}

type Slot = {
    lens: string,
    focal: number
}



type State = {
    boxes: Slot[][]
}

function executeInst(state: State, inst: Inst) {
    const boxIndex = hash(inst.lens);
    if (inst.kind === "add") {
        const slotIndex = state.boxes[boxIndex].findIndex(x => x.lens === inst.lens);
        if (slotIndex === -1) {
            state.boxes[boxIndex].push({
                lens: inst.lens,
                focal: inst.focal
            });
        } else {
            state.boxes[boxIndex][slotIndex].focal = inst.focal;
        }
    }
    else if (inst.kind === "remove") {
        const slotIndex = state.boxes[boxIndex].findIndex(x => x.lens === inst.lens);
        if (slotIndex !== -1) {
            state.boxes[boxIndex].splice(slotIndex, 1);
        }
    }
}

function initState(): State {
    return {
        boxes: new Array(256).fill(0).map(() => [])
    }
}

const input = await Deno.readTextFile("input.txt");
const inputs = input.split(",");

const insts = inputs.map(decodeInst);
const state = initState();

for (const inst of insts) {
    executeInst(state, inst);
}

console.log(state);

function calculateFocusingPower(state: State) {
    return state.boxes.map((slots, i) => slots.map((slot, j) => slot.focal * (j + 1) * (i + 1))
        .reduce((a, b) => a + b, 0))
        .reduce((a, b) => a + b, 0)
}

console.log(calculateFocusingPower(state))