Advent of Code: Historian Hysteria


Day 1 assignment

2024-12-01-generated.png

The Chief Historian is always present for the big Christmas sleigh launch, but nobody has seen him in months! Last anyone heard, he was visiting locations that are historically significant to the North Pole; a group of Senior Historians has asked you to accompany them as they check the places they think he was most likely to visit….

-- Day 1 - Advent of Code 2024

Solution in Java

Full source can be found: in GitHub

The first day of this years Advent Of Code was a relative simple assignment. With only two lists containing numbers requiring some basic sorting and comparing. The code that does this for the assignment can be found below:

 1    public void readInput() {  
 2        leftList = new ArrayList<>();  
 3        rightList = new ArrayList<>();  
 4        inputLoader.consumeLine(line -> {  
 5            String[] split = line.split(" +");  
 6            leftList.add(Integer.parseInt(split[0]));  
 7            rightList.add(Integer.parseInt(split[1]));  
 8        });  
 9  
10        Collections.sort(leftList);  
11        Collections.sort(rightList);  
12    }  

Part 1

For the first part the solution I chose was a simple comparison between the two values in the sorted array, as can be seen in part1() around line 8 in the solution below.

 1    public void part1() {  
 2        int sum = 0;  
 3        for (var i = 0; i < leftList.size(); i++) {  
 4            var left = leftList.get(i);  
 5            var right = rightList.get(i);  
 6  
 7            sum += left > right ? left - right : right - left;  
 8        }  
 9  
10        validator.part1(sum);  
11    }  

Part 2

For this part of todays AoC there is just a small change needed. As the assignment indicates we are no longer interested in the difference between the two lists, but rather the similarities.

This time, you’ll need to figure out exactly how often each number from the left list appears in the right list. Calculate a total similarity score by adding up each number in the left list after multiplying it by the number of times that number appears in the right list.
-- Day 1 - Advent of Code 2024

For this part of the assignment I still relied on the already sorted lists, but looped over the left list, whilst counting the occurrences of the same number in the right list. I added a small optimization that if we see the same number again (keep in mind they are sorted) we don’t recalculate but reuse the previous value.

 1public void part2() {  
 2    int similarity = 0;  
 3  
 4    int lastLeft = -1;  
 5    int lastCount = 0;  
 6    var countedRight = rightList.stream()  
 7            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));  
 8  
 9    for (int left : leftList) {  
10        if (lastLeft != left) {  
11            lastLeft = left;  
12            var rightCount = countedRight.get(left);  
13            lastCount = rightCount != null ? rightCount.intValue() : 0;  
14        }  
15  
16        similarity += lastCount * lastLeft;  
17    }  
18  
19    validator.part2(similarity);  
20}

See also