aoc2023/AdventOfCode/Day03.cs
2023-12-11 13:59:28 -08:00

159 lines
5.4 KiB
C#

using System.Text;
using System.Text.RegularExpressions;
namespace AdventOfCode;
public class Day03 : BaseDay
{
private readonly string _input;
private int total;
public Day03()
{
_input = File.ReadAllText(InputFilePath);
StringReader reader = new StringReader(_input);
Part1(reader);
//Console.WriteLine(char.IsPunctuation('/'));
//NotMine();
}
public void Part1(StringReader s)
{
string prev = "";
string curr = s.ReadLine();
string next = s.ReadLine();
int i = 0;
StreamWriter sw = new("mine.txt");
static bool isSymbolNotDot(char c)
{
return (char.IsSymbol(c) || char.IsPunctuation(c)) && c != '.';
}
bool isAdjacentToSymbols(int startIndex, int endIndex) //boolean for checking if number is adjacent to symbols
{
int trueStartInd = startIndex == 0 ? startIndex + 1 : startIndex; //in case number is at beginning of line
int trueEndInd = endIndex == curr.Length - 1 ? endIndex - 1 : endIndex; //in case number is at end of line
int stringLength = 2+trueEndInd-trueStartInd; //space around the number for the purpose of looking above and below its lines
if(!string.IsNullOrEmpty(prev))
{
foreach(char c in prev.Substring(trueStartInd-1, stringLength)) //check if there are any symbols above currline
{
if(isSymbolNotDot(c))
return true;
}
}
if(!string.IsNullOrEmpty(next))
{
foreach(char c in next.Substring(trueStartInd-1, stringLength)) //check if there are any symbols below currline
{
if(isSymbolNotDot(c))
return true;
}
}
return isSymbolNotDot(curr.ElementAt(trueStartInd-1)) || isSymbolNotDot(curr.ElementAt(trueEndInd));
//check if there are any symbols between number (if applicable)
}
while(curr != null)
{
int currIndex = 0;
while(curr.IndexOf(".", currIndex) != -1) //continue until end of line
{
if(char.IsDigit(curr.ElementAt(currIndex))) //if current item is a number
{
StringBuilder number = new();
int start = currIndex;
while(char.IsDigit(curr.ElementAt(currIndex)))
{
number.Append(curr.ElementAt(currIndex)); //put numbers together
currIndex++; //iterate
}
int end = currIndex;
if(isAdjacentToSymbols(start, end)) //if number is adjacent to symbols, add to sum
{
total += int.Parse(number.ToString());
Console.WriteLine(number + " is adjacent to symbols; current total: " + total + " on line " + (i+1));
sw.WriteLine("Total: " + total);
}
else
Console.WriteLine(number + " is not adjacent to symbols on line " + (i+1));
}
else //otherwise, continue moving through line
currIndex++;
}
prev = curr;
curr = next;
next = s.ReadLine();
i++;
}
}
public async void NotMine()
{
char[] Symbols = { '@', '#', '$', '%', '&', '*', '/', '+', '-', '=' };
string pattern = @"\d+";
List<string>? list;
list = new List<string>(await File.ReadAllLinesAsync(@"Inputs/03.txt"));
StreamWriter sw = new("notmine.txt");
int count = 0;
for (int row = 0; row < list.Count; row++)
{
for (int col = 0; col < list[row].Length; col++)
{
var c = list[row][col];
if (c == '.')
{
continue;
}
if (Symbols.Contains(c))
{
var res = Calculate(list[row - 1], col);
res += Calculate(list[row], col);
res += Calculate(list[row + 1], col);
count += res;
sw.WriteLine("Total: " + count);
}
}
}
Console.WriteLine(count);
int Calculate(string line, int col)
{
List<int> indexesToCheck = new List<int> { col - 1, col, col + 1 };
int count = 0;
MatchCollection matches = Regex.Matches(line, pattern);
foreach (Match match in matches)
{
string number = match.Value;
if (AnyIndexInList(indexesToCheck, match.Index, match.Length))
{
count += Int32.Parse(number);
}
}
return count;
}
static bool AnyIndexInList(List<int> list, int startIndex, int length)
{
for (int i = startIndex; i < startIndex + length; i++)
{
if (list.Contains(i))
{
return true;
}
}
return false;
}
}
public override ValueTask<string> Solve_1() => new(total.ToString());
public override ValueTask<string> Solve_2() => new(_input.Length.ToString());
}