const input = await Deno.readTextFile("input.txt");
const lines = input.split("\n").map(x => x.trim());
const graph = new Map<string, string[]>();
lines.forEach(line => {
    const [a, b] = line.split(": ");
    const elems = b.split(" ");
    if (!graph.has(a)) {
        graph.set(a, []);
    }
    const aElems = graph.get(a)!
    aElems.push(...elems.filter(x => !aElems.includes(x)));

    elems.forEach(elem => {
        if (!graph.has(elem)) {
            graph.set(elem, []);
        }
        const Elems = graph.get(elem)!
        if (!Elems.includes(a)){
            Elems.push(a);
        }
    });
});

function prettyPrint(graph: Map<string, string[]>, rename_fn = (x: string) => x) {
    let str = "";
    for (const [key, value] of graph) {
        str += `${rename_fn(key)}: ${value.map(x => rename_fn(x)).join(", ")}\n`;
    }
    return str;
}
console.log(prettyPrint(graph).slice(0, 100) + "...");
await Deno.writeTextFile("graph.txt", prettyPrint(graph));

let edges = 0;
for (const [key, value] of graph) {
    edges += value.length;
}
console.log(edges / 2, "edges");

const start = "ckf";
const renames = new Map<string, string>();
const bfsStack = [{ name: start, depth: 0, no: 0 }];
let no = 0;
let curDepth = 0;
// const visited = new Set<string>();
while (bfsStack.length > 0) {
    const current = bfsStack.shift()!;
    if (renames.has(current.name)) {
        continue;
    }
    if (current.depth !== curDepth) {
        curDepth = current.depth;
        console.log(curDepth, "depth");
        no = 0;
    }
    renames.set(current.name, `[${current.depth},${current.no}]`);
    for (const elem of graph.get(current.name)!) {
        if (!renames.has(elem) && bfsStack.every(x => x.name !== elem)) {
            bfsStack.push({
                name: elem,
                depth: current.depth + 1,
                no: no++,
            });
        }
    }
}

let sorted = [] as [string, string[]][];
for (const [key, value] of graph) {
    sorted.push([renames.get(key)!, value.map(x => renames.get(x)!)]);
}
sorted.sort((a, b) => {
    const ak = a[0].slice(1,-1).split(",");
    const bk = b[0].slice(1,-1).split(",");
    return ak[0] === bk[0] ? parseInt(ak[1]) - parseInt(bk[1]) : parseInt(ak[0]) - parseInt(bk[0]);
});

await Deno.writeTextFile("renames.txt", sorted.map(x => x[0] + ": " + x[1].join(", ")).join("\n"));