105 lines
3.5 KiB
C#
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;
|
|
}
|
|
}
|
|
} |