namespace WaitForIt; public class Program { public static async 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 parser = new PuzzleParser(); var input = await File.ReadAllLinesAsync(args[0]); var isPart2 = args.Length > 1 && args[1] == "part2"; long result = isPart2 ? parser .ParseRace(input) .CalculateNumberOfWaysToWin() : parser.ParseRaces(input) .Select(r => r.CalculateNumberOfWaysToWin()) .Aggregate((long)1, (acc, curr) => acc * curr); if (isPart2) { Console.WriteLine($"The number of ways to win is {result}."); } else { Console.WriteLine($"The total number of ways to win is {result}."); } return (int)result; } } /// /// Parses the puzzle input. /// public class PuzzleParser { private List GetValues(string input) => input .Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) .Skip(1) .Select(long.Parse) .ToList(); /// /// Parses the puzzle input to list of races /// /// The list of races /// A list containing instances of . public List ParseRaces(string[] racesInput) { var races = new List(); var durations = GetValues(racesInput[0]); var distances = GetValues(racesInput[1]); if (durations.Count != distances.Count) { throw new ArgumentException("The number of times and distances must be equal."); } for (int i = 0; i < durations.Count; i++) { races.Add(new Race(durations[i], distances[i])); } return races; } /// /// Parses the puzzle input as single race /// /// The list of races /// An instance of . public Race ParseRace(string[] racesInput) { var duration = string.Join("", GetValues(racesInput[0]).Select(v => v.ToString())); var distance = string.Join("", GetValues(racesInput[1]).Select(v => v.ToString())); return new Race(long.Parse(duration), long.Parse(distance)); } } /// /// Represents a Race /// /// The duration of the race /// The distance record /// An instance of . public class Race( long duration, long distanceRecord ) { /// /// Gets the duration of the race /// public long Duration { get; init; } = duration; /// /// Gets the distance record /// public long DistanceRecord { get; init; } = distanceRecord; /// /// Calculates the number of ways the race can be won. /// /// The number of ways the race can be won. public long CalculateNumberOfWaysToWin() { var numberOfWaysToWin = 0; for (var secsHeld = 0; secsHeld < Duration; secsHeld++) { var speed = 1 * secsHeld; var distance = speed * (Duration - secsHeld); if (distance > DistanceRecord) { numberOfWaysToWin++; } } return numberOfWaysToWin; } }