using AdventOfCode.Core; using AdventOfCode.Core.Shared.Grid; using System.Linq; using System.Text.RegularExpressions; namespace AdventOfCode.Solutions._2023 { public partial class Day03(InputReader reader) : IChallange { private InputReader _inputReader = reader; 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() { 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)).ToList(); return numbers.Where(number => symbols.Any(s => number.Intersect(s))).Select(num => int.Parse(num.Value)).Sum().ToString(); } public async Task GetSolutionPart2() { 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 gears = parts.Where(p => p.IsPartSymbol() && p.Section == "*").Select(symbol => new Point(symbol.X, symbol.Y, symbol.Section)).ToList(); return gears.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(); } [GeneratedRegex("(\\d+)", RegexOptions.Compiled)] private static partial Regex FindDigits(); [GeneratedRegex("(\\d+)|([^.])", RegexOptions.Compiled)] private static partial Regex FindPartItems(); } }