AdventOfCode/AdventOfCode.Solutions/2023/Day 15/Day15.cs
2024-12-01 10:17:24 +01:00

105 lines
3.5 KiB
C#

using AdventOfCode.Core.Shared.IO;
using System.Text;
namespace AdventOfCode.Solutions._2023
{
public class Day15 : IChallange
{
public int Year => 2023;
public int Day => 15;
private readonly IInputReader _inputReader;
public Day15(IInputReader inputReader)
{
_inputReader = inputReader;
_inputReader.SetInput(this);
}
public async Task<string> GetSolutionPart1()
{
string[] data = (await _inputReader.ReadAsString()).Split(',', StringSplitOptions.RemoveEmptyEntries);
int stringTotal = 0;
foreach (string s in data)
{
stringTotal += GetHash(s);
}
return stringTotal.ToString();
}
public async Task<string> GetSolutionPart2()
{
string[] data = (await _inputReader.ReadAsString()).Split(',', StringSplitOptions.RemoveEmptyEntries);
Dictionary<int, List<(string Label, int FocusLength)>> boxes = [];
foreach (string s in data)
{
if (s.EndsWith('-'))
{
string label = s[..^1];
// remove
int box = GetHash(label);
if (boxes.TryGetValue(box, out var lensBox))
{
var currentLens = lensBox.FirstOrDefault(l => l.Label == label);
if (!string.IsNullOrEmpty(currentLens.Label))
{
lensBox.Remove(currentLens);
}
}
continue;
}
if (char.IsDigit(s[^1]))
{
string label = s[..^2];
int box = GetHash(label);
int newFocal = int.Parse($"{s[^1]}");
if (boxes.TryGetValue(box, out var lensBox))
{
var newLens = (label, newFocal);
var currentLens = lensBox.FirstOrDefault(l => l.Label == label);
if (!string.IsNullOrEmpty(currentLens.Label))
{
int index = lensBox.IndexOf(currentLens);
lensBox[index] = newLens;
}
else
{
lensBox.Add(newLens);
}
}
else
{
boxes.Add(box, [(label, newFocal)]);
}
}
}
int total = 0;
foreach(var box in boxes)
{
total += GetBoxValue(box.Key + 1, box.Value);
}
return total.ToString();
}
private static int GetBoxValue(int boxId, List<(string Label, int FocusLength)> box) => box.Select((kvp, index) => boxId * (index + 1) * kvp.FocusLength).Sum();
private static int GetBoxValue(Dictionary<string, int> box) => box.Select((kvp, index) => (index + 1) * kvp.Value).Sum();
private static int GetHash(string s)
{
int segementTotal = 0;
foreach (byte value in Encoding.ASCII.GetBytes(s))
{
segementTotal += value;
segementTotal *= 17;
segementTotal %= 256;
}
return segementTotal;
}
}
}