Advent of Code 2024 - Day 1

Historian Hysteria

Written December 20th, 2024 | Attempted December 3rd, 2024

Tags:Advent of CodeC++

So from what I understand, the problems on the first day are typically “easy,” just to warm up people to the format I think. Guess that makes sense since this solution is relatively straight forward.

# Part 1

There's a lot of text but it basically boils down to the following steps:

  1. Read in the file (arguably the biggest part).
  2. Sort the two lists provided in the file.
  3. Find the first differences and compute the sum of them.

Here's an example of the input file, where the first list is on the left and the second list is on the right:

13   4
24   3
32   5
41   3
53   9
63   3

In C++, the code boils down to this:

1#include <bits/stdc++.h>
2
3int main() 
4{
5  std::ifstream input("day1_input.txt");
6
7  std::string line;
8  std::vector<int> list1 = {};
9  std::vector<int> list2 = {};
10
11  while (std::getline(input, line))
12  {
13    int delim_pos = line.find("   ");
14    std::string list1_elem = line.substr(0, delim_pos);
15    std::string list2_elem = line.substr(delim_pos);
16    list1.push_back(std::stoi(list1_elem));
17    list2.push_back(std::stoi(list2_elem));
18  }
19
20  std::sort(list1.begin(), list1.end());
21  std::sort(list2.begin(), list2.end());
22
23  int total_distance = std::transform_reduce(
24    list1.begin(), list1.end(), list2.begin(), 0, std::plus<int>(), 
25    [](int a, int b) { return std::abs(a - b); }
26  );
27
28  std::cout << "total distance: " << total_distance << std::endl;
29  input.close();
30  return 0;
31}

And because I'm an epic C++ programmer, here's the same thing but using ranges:

1#include <bits/stdc++.h>
2#include <ranges>
3
4int main()
5{
6  std::ifstream input("day1_input.txt");
7
8  std::string line;
9  std::string_view delim = "   ";
10  std::vector<int> list1 = {};
11  std::vector<int> list2 = {};
12
13  while (std::getline(input, line))
14  {
15    auto split = line | std::views::split(delim)
16                      | std::views::transform([](auto rng) {
17                        auto str = std::string(&*rng.begin(), std::ranges::distance(rng));
18                        return std::stoi(str);
19                      });
20    list1.push_back(*split.begin());
21    list2.push_back(*std::next(split.begin()));
22  }
23
24  std::ranges::sort(list1);
25  std::ranges::sort(list2);
26
27  int total_distance = std::ranges::fold_left(
28    std::views::iota(0, (int)list1.size())
29    | std::views::transform([&list1, &list2](int i) {
30      return std::abs(list1[i] - list2[i]);
31    }), 
32    0, std::plus<int>()
33  );
34
35  std::cout << "total distance: " << total_distance << std::endl;
36  input.close();
37  return 0;
38}

# Part 2

Part 2 is a bit more involved but it's still relatively simple. Basically:

  1. Read in the file (again).
  2. For the first unique instance of a number in the first list, count the number of occurrences in the second list. The base “similarity score” is the product of the unique number and the number of occurrences.
  3. For every repeat occurrence in the first list, the score increases by the product computed before.
  4. Then compute the sum of the similarity scores.

Here's the code:

1#include <bits/stdc++.h>
2
3int main()
4{
5  std::ifstream input("day1_input.txt");
6
7  std::string line;
8  std::vector<int> list1 = {};
9  std::vector<int> list2 = {};
10
11  while (std::getline(input, line))
12  {
13    int delim_pos = line.find("   ");
14    list1.push_back(std::stoi(line.substr(0, delim_pos)));
15    list2.push_back(std::stoi(line.substr(delim_pos + 3)));
16  }
17
18  std::unordered_map<int, std::pair<int, int>> similarity_scores = {};
19  for (const auto& id : list1)
20  {
21    if (similarity_scores.contains(id)) 
22    {
23      auto previous_pair = similarity_scores.at(id);
24      similarity_scores.at(id) = std::make_pair(
25        previous_pair.first, 
26        previous_pair.second + previous_pair.first
27      );
28    }
29
30    int instances_in_second = std::count(list2.begin(), list2.end(), id);
31    similarity_scores.insert({
32      id, 
33      std::make_pair(id * instances_in_second, id * instances_in_second)
34    });
35  }
36
37  int total_similarity_score = std::accumulate(similarity_scores.begin(), similarity_scores.end(), 0, 
38    [](int acc, const std::pair<int, std::pair<int, int>>& pair) {
39      return acc + pair.second.second;
40    }
41  );
42
43  std::cout << "total similarity score: " << total_similarity_score << std::endl;
44  input.close();
45  return 0;
46}

Again, pretty simple stuff that's good for a warm-up. Though, I've heard the problems get harder as the days go on. Here's hoping I can get past day 5 lmao.