Advent of Code 2023: Day 15 Lens Library
Grant Riordan
Posted on January 7, 2024
Day 15 : Lens
Overview
Today’s challenge Part1 was pretty straightforward. Simply apply some arithmetic to each character in a string and then Sum() them all up.
Part 2 was a little more complex in that you were requested to maintain lenses using the hashed values and 255 boxes.
Reading Input
The program reads a comma-separated string from the file and splits it into an array of strings using the Split
method. The StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries
ensure that empty entries and leading/trailing whitespaces are removed.
var inputs = File.ReadAllText("input.txt").Split(',');
Hashing Algorithm
The Hash
function processes each string and applies a HASH algorithm to calculate a numeric value. This value is then used to determine the position of the lens in the box (par2).
int Hash(string str)
{
int currentValue = 0;
foreach (char c in str)
{
currentValue += (int)c;
currentValue *= 17;
currentValue %= 256;
}
return currentValue;
}
Part 1 Calculation
The program iterates over the input strings, applies the HASH algorithm, and accumulates the results to get the part1
value. The result is then displayed.
int part1 = 0;
foreach (string input in inputs)
{
part1 += Hash(input);
}
Console.WriteLine($"Solution 1: {part1}");
Part 2: Lens Organization in Boxes
The second part tackles the organization of lenses into boxes based on a sequence of operations specified in the input.
Initializing Boxes and Focal Lengths
Boxes are represented using a list of lists (List<List<string>>
), and focal lengths are stored in a dictionary (Dictionary<string, int>
). The code uses LINQ to initialize the boxes, ie create 255 entries in the list all with empty lists as their values. Check out my series on Linq if you’re not familiar.
List<List<string>> boxes = Enumerable.Range(0, 256)
.Select(_ => new List<string>())
.ToList();
Dictionary<string, int> focalLengths = new Dictionary<string, int>();
Processing Steps
The program iterates over the input steps, which consist of lens-related operations ('=' for adding a lens and '-' for removing a lens).
foreach (string step in inputs)
{
// Processing code for adding or removing lenses
}
Adding Lenses
For steps with '=', the code splits the input to get the label and focal length. It then calculates the box index using the HASH algorithm. If the box already contains the label, it updates the existing lens, otherwise, it adds a new lens.
if (step.Contains('='))
{
string[] parts = step.Split('=');
string label = parts[0];
int focalLength = int.Parse(parts[1]);
int box = Hash(label);
focalLengths[label] = focalLength;
if (boxes[box].Contains(label))
{
int labelIndex = boxes[box].IndexOf(label);
boxes[box][labelIndex] = label;
}
else
{
boxes[box].Add(label);
}
}
Removing Lenses
For steps with '-', the code removes the specified lens from the box.
if (step.Contains('-'))
{
string label = step[..^1];
int box = Hash(label);
boxes[box].Remove(label);
}
Solution 2 Calculation
The final solution involves calculating a score based on the box, slot, and focal length. LINQ is used to achieve this concise calculation.
var solution2 = boxes.SelectMany((box, boxIndex) =>
box.Select((label, slotIndex) =>
(boxIndex + 1) * (slotIndex + 1) * focalLengths[label]))
.Sum();
Console.WriteLine($"Solution 2: {solution2}");
There you have it Day 15 complete. As always drop me a follow for further articles / and discussions. Or check out my twitter.
Posted on January 7, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.