import fs from "node:fs"; const data = fs.readFileSync("./inputs/input", "utf8"); console.log( "part one:", data .split("\n") .slice(0, -1) // remove empty trailing newline .map( (v) => v.split(" ").filter((c) => c) // abusing js string nullity to remove empty members ) .reduce( (result, current) => { // build two arrays, one of each column result[0].push(parseInt(current[0], 10)); result[1].push(parseInt(current[1], 10)); return result; }, [[], []] as Array> ) .map((list) => [...list].sort()) // hacky return-sorted-values step .reduce((result, current) => { // rotate arrays into pairs current.forEach((n, i) => { result[i] === undefined ? (result[i] = [n]) : result[i].push(n); }); return result; }, [] as Array>) .reduce((result, current) => { // do the math return result + Math.abs(current[0] - current[1]); }, 0) ); console.log( "part two:", Object.entries( data .split("\n") .slice(0, -1) // remove empty trailing newline .map( (v) => v.split(" ").filter((c) => c) // abusing js string nullity to remove empty members ) .reduce((result, current) => { // build one object that contains the full set of frequencies result[current[0]] = !result[current[0]] ? [1, 0] : [result[current[0]][0] + 1, result[current[0]][1]]; result[current[1]] = !result[current[1]] ? [0, 1] : [result[current[1]][0], result[current[1]][1] + 1]; return result; }, [] as Array>) ).reduce((result, current) => { // and then just reduce down the object. return result + parseInt(current[0], 10) * current[1][0] * current[1][1]; }, 0) );