import fs from 'fs'; export type Cubes = { blue: number; red: number; green: number; } export type Game = { id: number; rounds: Cubes[]; } export const parseGame = (input: string): Game => { const [gameId, roundsInput] = input.split(':'); const id = parseInt(gameId.split(' ')[1], 10); const rounds = roundsInput.split(';').map(round => { return round.trim().split(',').map(cube => cube.trim()).reduce((total, cube) => { const [amount, color] = cube.split(' '); total[color as keyof Cubes] = parseInt(amount, 10); return total; }, {blue: 0, green: 0, red: 0} as Cubes); }); return { id, rounds } } export const calculatePossibleGames = (games: Game[], limits: Cubes): number => { const possibleGames = games.filter(game => { return game.rounds.every(round => { return Object.keys(round).every(color => { return round[color as keyof Cubes] <= limits[color as keyof Cubes]; }); }); }); return possibleGames.reduce((total, game) => total + game.id, 0); } const minimumCubesRequiredForGame = (game: Game): Cubes => { return game.rounds.reduce((total, round) => { Object.keys(round).forEach(color => { total[color as keyof Cubes] = Math.max(total[color as keyof Cubes], round[color as keyof Cubes]); }); return total; }, {blue: 0, green: 0, red: 0} as Cubes); } export const calculateMinimumCubePowers = (games: Game[]): number => { const minimumCubes = games.map(minimumCubesRequiredForGame); return minimumCubes.reduce((total, cubes) => { return total + (cubes.blue * cubes.green * cubes.red); }, 0); } export const runDayTwo = () => { const input = fs.readFileSync('./inputs/day_two_input.txt', 'utf8').split('\n').filter(Boolean); const games = input.map(parseGame); const limits = { blue: 14, red: 12, green: 13 }; console.log(calculatePossibleGames(games, limits)); console.log(calculateMinimumCubePowers(games)); } runDayTwo();