Thursday, July 3, 2025

Advent of Code 2024 Day 1 part 2

 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

Switch

 Other than if/if-else/if-else if-else and the ternary operator, there is yet another common and important conditional expression in Java th...