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).
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]));
}
}