Grant Riordan

Posted on

# Advent of Code 2023: Day 15 Lens Library

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.

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
}
``````

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
{
}
}
``````

### 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.