Advent of Code 23: Day 2 Cubes Conundrum
Tags: adventofcode, csharp, programming
Published: 2023-12-03 01:56:19

## Day 2

[AoC Problem Page](https://adventofcode.com/2023/day/2)

Day 2 was easier than the first day, however, I felt it a lot more time-consuming!


**Part 1** was to firstly work out which games were valid by checking if each set of coloured cubes was feasible based on some max values (red =12, green = 13, and blue =14). 

Once you had those values, it was just a case of simply summing the game numbers of the valid games.

** Part 2** - again not too difficult, some would even argue it was simpler than the first part. Now you have all the colours and their amounts, it was just a case of finding all the highest amounts of each colour. 

I found this Challenge more a parsing exercise, rather than a huge coding challenge. 

### Mistakes made along the way:

I wasted too much time trying to parse each part of the string, splitting on `;` characters and `,` characters which proved very time-consuming. Then I remembered the power of Regex & named grouping (which makes using the Group class a lot easier). 

### Solution, and as always it's available on my Github Repo (link in bio). 

```csharp
using System.Text.RegularExpressions;

Dictionary<string, int> maxValues = new()
{
    { "red", 12 },
    { "green", 13 },
    { "blue", 14 }
};

bool isValidGame(Game game) => game.sets.All(isValidSet);

bool isValidSet(GameSet set) => set.red <= maxValues["red"] && set.green <= maxValues["green"] && set.blue <= maxValues["blue"];

GameSet FindMaxSets(List<GameSet> sets) =>
        new GameSet(
            red: sets.Max(s => s.red),
            green: sets.Max(s => s.green),
            blue: sets.Max(s => s.blue)
        );

int ChallengePart1(Game[] games)
{
  return games.Where(isValidGame).Select(x => x.gameId).Sum();
}

int ChallengePart2(Game[] games) =>
       games.Select(game => FindMaxSets(game.sets))
            .Select(x => x.red * x.green * x.blue)
            .Sum();

string[] lines = File.ReadAllLines("./test.txt");
Game[] games = lines.Select(Game.Parse).ToArray();


Console.WriteLine(ChallengePart1(games));
Console.WriteLine(ChallengePart2(games));


record GameSet(int green, int red, int blue)
{

  public static List<GameSet> ParseSets(string setInfo) => setInfo
    .Split(';', StringSplitOptions.TrimEntries)
    .Select(ParseSet)
    .ToList();

  public static GameSet ParseSet(string line)
  {
    var parts = line.Split(',', StringSplitOptions.TrimEntries);
    var regEx = new Regex(@"(?<id>\d+) (?<color>red|green|blue)", RegexOptions.IgnoreCase);
    Dictionary<string, int> colors = new(){
     {"red",0},
     {"blue",0},
     {"green",0}
    };

    foreach (var part in parts)
    {
      Match game = regEx.Match(part);
      Group id = game.Groups["id"];
      Group color = game.Groups["color"];

      colors[color.Value] = int.Parse(id.Value);
    }
    return new GameSet(colors["green"], colors["red"], colors["blue"]);
  }
}

record Game(int gameId, List<GameSet> sets)
{

  public static Game Parse(string line)
  {
    var parts = line.Split(':', StringSplitOptions.TrimEntries);
    string pattern = @"\d+";
    var id = Regex.Match(parts[0], pattern).Value;

    return new Game(int.Parse(id), GameSet.ParseSets(parts[1]));
  }

}
```