Post

# Advent of Code 2022, Day 4 - Sanitizer

## Preface

The objective of the fourth day is available on the advent of code website, so it won’t be shared here. On this page only the steps of achieving a solution are given with a solution build in Kotlin.

## Design

When reading through the assignment we can identify in what kind of model we’d like to put our raw data. So the first step that we’re going to do is think about our data structure.

So we’ve got the following raw input.

```1 2 3 4 5 6 2-4,6-8 2-3,4-5 5-7,7-9 2-8,3-7 6-6,4-6 2-6,4-8 ```

Were each line are two elves comparing their clean up range. This means that on the first line one elve is responsible for cleaning up range 2 through 4 and another one is responsible for the range 6 through 8.

This means that we want to get the following data structure.

```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 [ { // Line 1 { 2, 4 }, // First elve { 6, 8 } // Second elve }, { // Line 2 { 2, 3 }, // First elve { 4, 5 } // Second elve }, { // Line 3 { 5, 7 }, // First elve { 7, 9 } // Second elve }, { // Line 4 { 2, 8 }, // First elve { 3, 7 } // Second elve }, { // Line 5 { 6, 6 }, // First elve { 4, 6 } // Second elve }, { // Line 6 { 2, 6 }. // First elve { 4, 8 } // Second elve } ] ```

In this data structure we have a list with pairs where each pair is made up of two pairs, so the data type is going to be `List<Pair<Pair<Int, Int>, Pair<Int, Int>>>`. Where the list is equal to all the lines, the first pair is equal to both elves and the inner pairs are the ranges that each elve needs to clean up.

## Implementation

### Sanitizer

Now we now how we want our data structure to look like, we can start creating the `getItems(): List<Pair<Pair<Int, Int>, Pair<Int, Int>>>` method inside our `Sanitizer` class.

```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Sanitizer( private val resource: URL? ) { fun getItems(): List<Pair<Pair<Int, Int>, Pair<Int, Int>>>? = resource ?.readText() ?.split("\n") ?.map { // Step 1 val ranges = it.split(",") Pair(ranges, ranges) } ?.map { // Step 2 val firstElveRanges = it.first.split("-") val secondElveRanges = it.second.split("-") // Step 3 Pair( Pair(firstElveRanges.toInt(), firstElveRanges.toInt()), Pair(secondElveRanges.toInt(), secondElveRanges.toInt()) ) } } ```

At step 1 we have each line of two ranges, so we need to split up that line that get two ranges. We do this by splitting the line on the `-` character and putting that result into an pair. Then at step 2 we split each item in the pair on the `,` character, so we have the start and end range of each elve. We then convert that result to an integer an put it in another pair at step 3.

### Test case

To validate that our logic works as expected, we create a test case based on the sample data from the assignment. This way we can validate that our sanitizer gives us the correct data structure which we can use in the assignments.

```1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 class SanitizerTest { @Test fun testGetItems() { // Arrange val resource = {}::class.java.getResource("/input.txt") val sut = Sanitizer(resource) val expectedItems = listOf( Pair( Pair(2, 4), Pair(6, 8) ), Pair( Pair(2, 3), Pair(4, 5) ), Pair( Pair(5, 7), Pair(7, 9) ), Pair( Pair(2, 8), Pair(3, 7) ), Pair( Pair(6, 6), Pair(4, 6) ), Pair( Pair(2, 6), Pair(4, 8) ) ) // Act val result = sut.getItems() // Assert assertContentEquals(expectedItems, result) } } ```