To get their big prize at Christmas, the elves you’re helping by solving these puzzles need you to solve two puzzles a day—the second always uses the same input as the first—to get 50 stars by Christmas. (Of course, you can solve the puzzles anytime after they’re released, and there’s no penalty for solving a puzzle outside of the December in which it came out.)
The second part of the December 1, 2024 puzzle, which you’ll only see if you
finish the first one, deals with what the elves call “similarity.” That doesn’t
mean anything outright, but they give a definition for this puzzle specifically:
the product of a left-list number and the number of times it shows up in the
right list.
All the other logic can stay—you still need to take
advantage of the reading of the file into two lists, anyway.
What changes in part 2 is that you now have an extra method for calculating this
new metric:
public int
calculateSimilarity(List<Integer> leftList, List<Integer>
rightList) {
int
similarity = 0;
// multiply
each number in the left list by how many occurrences it has in the right list
// and keep
a running total of these products
for (int
elem : leftList) {
int
count = frequency(rightList, elem);
similarity += (count * elem);
}
// return
the total
return
similarity;
}
The easiest way to count the number of occurrences is the way I’ve done it here—with
Collections.frequency().
Collections.frequency() takes in two parameters: the collection through which
you want to search, and the element for which you want to search within that
collection; it returns the number of times the element appears.
The loop, therefore:
·
Goes through every element of the left list
·
Determines the frequency of that element in the
left list
·
Multiplies the frequency by the element’s own
value
·
Adds that product to the global measurement of
similarity
·
Returns the total once everything has been
processed
The whole code for Day 1, parts 1 and 2, in 2024, is as follows:
package org.example.c01;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static java.util.Collections.*;
public class Solution {
static
List<Integer> leftList = new ArrayList<>();
static
List<Integer> rightList = new ArrayList<>();
public static
void main(String[] args) throws IOException {
Solution
solution = new Solution();
solution.readFile(args[0]);
sort(leftList);
sort(rightList);
int result =
solution.calculateDistance(leftList, rightList);
System.out.println("total distance: " + result);
int
similarity = solution.calculateSimilarity(leftList, rightList);
System.out.println("similarity = " + similarity);
}
private void
readFile(String fileName) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line;
while ((line
= reader.readLine()) != null) {
String[] arr = line.split("\t");
leftList.add(Integer.parseInt(arr[0]));
rightList.add(Integer.parseInt(arr[1]));
}
}
public int
calculateDistance(List<Integer> leftList, List<Integer> rightList)
{
int
totalDistance = 0;
// pair the
smallest numbers together
// then the
next smallest
// etc.
// and
calculate the running sum of the absolute distances between the pairs
for (int i =
0; i < leftList.size(); i++) {
totalDistance += Math.abs(leftList.get(i) - rightList.get(i));
}
// return
the sum
return
totalDistance;
}
public int
calculateSimilarity(List<Integer> leftList, List<Integer>
rightList) {
int
similarity = 0;
// multiply
each number in the left list by how many ocurrences it has in the right list
// and keep
a running total of these products
for (int
elem : leftList) {
int
count = frequency(rightList, elem);
similarity += (count * elem);
}
// return
the total
return
similarity;
}
}
No comments:
Post a Comment