using System.Text.RegularExpressions; namespace AdventOfCode.Solutions._2023 { public partial class Day03 : IChallange { public int Year => 2023; public int Day => 3; private readonly InputReader _inputReader; public Day03(InputReader inputReader) { _inputReader = inputReader; _inputReader.SetInput(this); } private class PartNumber { public int X { get; set; } public int Y { get; set; } public string Section { get; set; } = string.Empty; public int Length => Section.Length; public bool IsDigit() => Section.All(char.IsDigit); public bool IsPartSymbol() => !IsDigit(); } public async Task GetSolutionPart1() { var (Numbers, Symbols) = await GetNumbersAndSymbols(); return Numbers .Where(number => Symbols.Any(s => number.Intersect(s))) .Select(num => int.Parse(num.Value)) .Sum() .ToString(); } public async Task GetSolutionPart2() { var (Numbers, Symbols) = await GetNumbersAndSymbols(); return Symbols .Where(s => s.Value == '*') .Select(g => Numbers.Where(n => n.Intersect(g))) .Where(n => n.Count() == 2) .Select(num => int.Parse(num.First().Value) * int.Parse(num.Last().Value)) .Sum() .ToString(); } private async Task<(List Numbers, List Symbols)> GetNumbersAndSymbols() { List parts = []; int row = 0; await foreach (string line in _inputReader.ReadAsStringLine()) { row++; MatchCollection matchCollection = FindPartItems().Matches(line); parts.AddRange(matchCollection.Select(match => new PartNumber { X = match.Index + 1, Y = row, Section = match.Value })); } List numbers = parts.Where(p => p.IsDigit()).Select(number => new Rectangle(new Point(number.X - 1, number.Y - 1), new Point(number.X + number.Length, number.Y + 1), number.Section)).ToList(); List symbols = parts.Where(p => p.IsPartSymbol()).Select(symbol => new Point(symbol.X, symbol.Y, symbol.Section[0])).ToList(); return (numbers, symbols); } [GeneratedRegex("(\\d+)", RegexOptions.Compiled)] private static partial Regex FindDigits(); [GeneratedRegex("(\\d+)|([^.])", RegexOptions.Compiled)] private static partial Regex FindPartItems(); } }