using System.Text; namespace AdventOfCode.Solutions._2023 { public class Day15 : IChallange { public int Year => 2023; public int Day => 15; private readonly InputReader _inputReader; public Day15(InputReader inputReader) { _inputReader = inputReader; _inputReader.SetInput(this); } public async Task 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 GetSolutionPart2() { string[] data = (await _inputReader.ReadAsString()).Split(',', StringSplitOptions.RemoveEmptyEntries); Dictionary> 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 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; } } }