namespace CubeConundrum; public class Program { public async static Task Main(string[] args) { if (args.Length is 0) { Console.WriteLine("Please provide a path to the input file."); return -1; } if (File.Exists(args[0]) is false) { Console.WriteLine("The provided file does not exist."); return -2; } var puzzleParser = new PuzzleParser(); var puzzleSolver = new PuzzleSolver(); var input = await File.ReadAllLinesAsync(args[0]); var games = input.Select(puzzleParser.ParseGame); var result = args.Length > 1 && args[1] == "part2" ? puzzleSolver.SumGameMinimumPowers(games) : puzzleSolver.SumPossibleGameIds(games); if (args.Length > 1 && args[1] == "part2") { Console.WriteLine($"The sum of the minimum powers of all games is {result}."); } else { Console.WriteLine($"The sum of all possible game ids is {result}."); } return result; } } /// /// Puzzle solver. /// public class PuzzleSolver { /// /// The maximum number of cubes that can be used in a game. /// private readonly int _maxCubeCount = 39; /// /// The maximum number of red cubes that can be used in a game. /// private readonly int _maxRedCubeCount = 12; /// /// The maximum number of green cubes that can be used in a game. /// private readonly int _maxGreenCubeCount = 13; /// /// The maximum number of blue cubes that can be used in a game. /// private readonly int _maxBlueCubeCount = 14; /// /// Determines whether a result is possible. /// /// The result to check. /// True if the result is possible, otherwise false. public bool IsResultPossible(Result result) => result.TotalCubeCount <= _maxCubeCount && result.RedCubeCount <= _maxRedCubeCount && result.GreenCubeCount <= _maxGreenCubeCount && result.BlueCubeCount <= _maxBlueCubeCount; /// /// Determines whether a game is possible. /// /// The game to check. /// True if the game is possible, otherwise false. public bool IsGamePossible(Game game) => game.Results.All(IsResultPossible); /// /// Sums all possible game ids. /// /// The games to sum. /// The sum of all possible game ids. public int SumPossibleGameIds(IEnumerable games) => games .Where(IsGamePossible) .Sum(g => g.Id); /// /// Sums the minimum powers of all games. /// /// The games to sum. /// The sum of the minimum powers of all games. public int SumGameMinimumPowers(IEnumerable games) => games .Select(g => g.PowerOfMinimumCubesNeeded) .Sum(); } /// /// Puzzle parser responsible for parsing puzzle input. /// public class PuzzleParser { /// /// Parses a cube from a string. /// /// The string to parse. /// An instance of . public CubeCollection ParseCube(string cubeString) { var parts = cubeString.Split(' '); var count = int.Parse(parts[0]); var color = Enum.Parse(parts[1], true); return new() { Count = count, Color = color }; } /// /// Parses a result from a string. /// /// The string to parse. /// An instance of . public Result ParseResult(string resultString) { var cubes = resultString .Split(',') .Select(s => s.Trim()) .Select(ParseCube) .ToList(); return new() { Cubes = cubes }; } /// /// Parses a game from a string. /// /// The string to parse. /// An instance of . public Game ParseGame(string gameString) { var parts = gameString.Split(':'); var gameId = int.Parse(parts[0].Split(' ')[1]); var results = parts[1] .Split(';') .Select(s => s.Trim()) .Select(ParseResult) .ToList(); return new() { Id = gameId, Results = results }; } } /// /// Represents a game. /// public class Game { /// /// The id of the game. /// public int Id { get; set; } /// /// The results of the game. /// public List Results { get; set; } = []; private int MinimumRedCubesNeeded => Results.Max(r => r.RedCubeCount); private int MinimumGreenCubesNeeded => Results.Max(r => r.GreenCubeCount); private int MinimumBlueCubesNeeded => Results.Max(r => r.BlueCubeCount); /// /// The power of the minimum number of each cube type needed to play the game. /// public int PowerOfMinimumCubesNeeded => MinimumRedCubesNeeded * MinimumGreenCubesNeeded * MinimumBlueCubesNeeded; } /// /// Represents a result. /// public class Result { /// /// The cubes in the result. /// public List Cubes { get; set; } = []; /// /// The total number of cubes in the result. /// public int TotalCubeCount => Cubes.Sum(c => c.Count); /// /// The number of red cubes in the result. /// public int RedCubeCount => Cubes.Where(c => c.Color == CubeColor.Red).Sum(c => c.Count); /// /// The number of green cubes in the result. /// public int GreenCubeCount => Cubes.Where(c => c.Color == CubeColor.Green).Sum(c => c.Count); /// /// The number of blue cubes in the result. /// public int BlueCubeCount => Cubes.Where(c => c.Color == CubeColor.Blue).Sum(c => c.Count); } /// /// Represents cubes of a given color. /// public class CubeCollection { /// /// The number of cubes. /// public int Count { get; set; } /// /// The color of the cubes. /// public CubeColor Color { get; set; } } /// /// Represents a cube color. /// public enum CubeColor { /// /// The red cube color. /// Red, /// /// The green cube color. /// Green, /// /// The blue cube color. /// Blue }