using AdventOfCode.Core; 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.Length > 1; public bool IsPartSymbol() => !IsDigit(); public List XRange => Enumerable.Range(X, Length).ToList(); public List XRangeWithSpace => Enumerable.Range(X-1, Length+2).ToList(); public List YRange => Enumerable.Range(Y - 1, 3).ToList(); public override string ToString() { return $"[{Y},{X}] {Section}"; } } public async Task GetSolutionPart1() { List parts = []; int row = 0; int total = 0; await foreach (string line in _inputReader.ReadAsStringLine()) { MatchCollection matchCollection = FindPartItems().Matches(line); parts.AddRange(matchCollection.Select(match => new PartNumber { X = match.Index, Y = row, Section = match.Value })); row++; } List numbers = parts.Where(p => p.IsDigit()).ToList(); List symbols = parts.Where(p => p.IsPartSymbol()).ToList(); foreach(PartNumber number in numbers) { var yfilter = symbols.Where(symbol => number.YRange.Contains(symbol.Y)); var xfilter = yfilter.Where(symbol => number.XRangeWithSpace.Intersect(symbol.XRange).Any()); bool isPartNumber = xfilter.Any(); if(isPartNumber) { Console.WriteLine("Adding " + number.ToString()); total += int.Parse(number.Section); Console.WriteLine("Total: " + total.ToString()); } } //Grid grid = await _inputReader.ReadToGrid(); //int row = 0; // //await foreach(string line in _inputReader.ReadAsStringLine()) //{ // MatchCollection matchCollection = FindDigits().Matches(line); // // foreach (Match match in matchCollection.Cast()) // { // var section = grid.GetSection(match.Index - 1, row - 1, match.Index + match.Length, row + 1).ToList(); // bool isPartNumber = section.Any(n => !(n.Char == '.' || (n.Char >= '0' && n.Char <= '9'))); // if (isPartNumber) { // total += int.Parse(match.Value); // } // } // // row++; //} return total.ToString(); } public async Task GetSolutionPart2() { List parts = []; int row = 0; int total = 0; await foreach (string line in _inputReader.ReadAsStringLine()) { MatchCollection matchCollection = FindPartItems().Matches(line); parts.AddRange(matchCollection.Select(match => new PartNumber { X = match.Index, Y = row, Section = match.Value })); row++; } List numbers = parts.Where(p => p.IsDigit()).ToList(); List gears = parts.Where(p => p.IsPartSymbol() && p.Section == "*").ToList(); foreach (PartNumber gear in gears) { // check if there are 2 numbers around //List ratios = GetSection(numbers, gear).ToList(); //if (ratios.Count != 2) // continue; //int totalRatio = int.Parse(ratios[0].Section) * int.Parse(ratios[1].Section); //total += totalRatio; } return total.ToString(); } [GeneratedRegex("(\\d+)", RegexOptions.Compiled)] private static partial Regex FindDigits(); [GeneratedRegex("(\\d+)|([^.])", RegexOptions.Compiled)] private static partial Regex FindPartItems(); } }