const sample = await Deno.readTextFile("sample.txt"); const input = await Deno.readTextFile("input.txt"); type Game = { number: number; highest: Draw; draws: Draw[]; }; interface Draw { blue: number; red: number; green: number; } const parseDraws = (draw: string): Draw => draw.split(", ").map((cube) => (cube.match(/^(\d+)\ (\w+)$/) || [])) .reduce( (draw, [_, amount, color]): Draw => ({ ...draw, [color]: parseFloat(amount), }), { blue: 0, red: 0, green: 0 }, ); const parseGame = (game: string, index: number): Game => { const draws = (game .split(": ") .pop() ?? "") .split("; ") .map(parseDraws); const highest = { green: draws.reduce((max, d) => Math.max(d.green, max), 0), blue: draws.reduce((max, d) => Math.max(d.blue, max), 0), red: draws.reduce((max, d) => Math.max(d.red, max), 0), }; return ({ number: index + 1, highest, draws, }); }; const solvePart1 = (data: string, match: Draw): number => data .split("\n") .filter(Boolean) .map(parseGame) .filter((game) => game.highest.blue <= match.blue && game.highest.green <= match.green && game.highest.red <= match.red ) .reduce((sum, { number }) => sum + number, 0); console.log("Sample:", solvePart1(sample, { red: 12, green: 13, blue: 14 })); // 8 console.log("Input", solvePart1(input, { red: 12, green: 13, blue: 14 })); // 2101 const solvePart2 = (data: string): number => data .split("\n") .filter(Boolean) .map(parseGame) .reduce( (sum, { highest }) => sum + (highest.blue * highest.green * highest.red), 0, ); console.log("Sample2:", solvePart2(sample)); // 2286 console.log("Input", solvePart2(input)); // 58269