123 lines
4.4 KiB
C#
123 lines
4.4 KiB
C#
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<int> XRange => Enumerable.Range(X, Length).ToList();
|
|
|
|
public List<int> XRangeWithSpace => Enumerable.Range(X-1, Length+2).ToList();
|
|
|
|
public List<int> YRange => Enumerable.Range(Y - 1, 3).ToList();
|
|
|
|
public override string ToString()
|
|
{
|
|
return $"[{Y},{X}] {Section}";
|
|
}
|
|
}
|
|
|
|
public async Task<string> GetSolutionPart1()
|
|
{
|
|
List<PartNumber> 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<PartNumber> numbers = parts.Where(p => p.IsDigit()).ToList();
|
|
List<PartNumber> 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<Node> grid = await _inputReader.ReadToGrid<Node>();
|
|
//int row = 0;
|
|
//
|
|
//await foreach(string line in _inputReader.ReadAsStringLine())
|
|
//{
|
|
// MatchCollection matchCollection = FindDigits().Matches(line);
|
|
//
|
|
// foreach (Match match in matchCollection.Cast<Match>())
|
|
// {
|
|
// 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<string> GetSolutionPart2()
|
|
{
|
|
List<PartNumber> 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<PartNumber> numbers = parts.Where(p => p.IsDigit()).ToList();
|
|
List<PartNumber> gears = parts.Where(p => p.IsPartSymbol() && p.Section == "*").ToList();
|
|
|
|
foreach (PartNumber gear in gears)
|
|
{
|
|
// check if there are 2 numbers around
|
|
//List<PartNumber> 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();
|
|
}
|
|
} |