Skip to content

Instantly share code, notes, and snippets.

@Xowap
Created December 2, 2024 01:42
Show Gist options
  • Save Xowap/5efdcdeb2bfd04d186351dd9987dd769 to your computer and use it in GitHub Desktop.
Save Xowap/5efdcdeb2bfd04d186351dd9987dd769 to your computer and use it in GitHub Desktop.
Advent of Code - Day 1 - v2
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <unordered_map>
#include <cmath>
#include <stdexcept>
#include <sstream>
struct Args {
std::string input_file;
};
Args parse_args(int argc, char* argv[]) {
Args args;
args.input_file = "-";
for (int i = 1; i < argc; i++) {
std::string arg = argv[i];
if (arg == "-i" || arg == "--input-file") {
if (i + 1 < argc) {
args.input_file = argv[++i];
}
}
}
return args;
}
std::pair<int, int> parse_line(const std::string& line) {
int state = 0;
std::string num1, num2;
for (char c : line) {
if (state == 0) {
if (std::isdigit(c)) {
num1 += c;
state = 1;
} else {
return {-1, -1};
}
} else if (state == 1) {
if (std::isdigit(c)) {
num1 += c;
} else if (std::isspace(c)) {
state = 2;
} else {
return {-1, -1};
}
} else if (state == 2) {
if (std::isdigit(c)) {
num2 += c;
state = 3;
} else if (std::isspace(c)) {
// do nothing
} else {
return {-1, -1};
}
} else if (state == 3) {
if (std::isdigit(c)) {
num2 += c;
} else {
return {-1, -1};
}
}
}
if (state == 3 && !num1.empty() && !num2.empty()) {
return {std::stoi(num1), std::stoi(num2)};
} else {
return {-1, -1};
}
}
std::pair<std::vector<int>, std::vector<int>> parse_input(std::istream& input) {
std::vector<int> list1, list2;
std::string line;
while (std::getline(input, line)) {
auto [num1, num2] = parse_line(line);
if (num1 != -1 && num2 != -1) {
list1.push_back(num1);
list2.push_back(num2);
} else {
throw std::runtime_error("Invalid line: " + line);
}
}
return {list1, list2};
}
int compute_distance(const std::vector<int>& list1, const std::vector<int>& list2) {
std::vector<int> s1 = list1;
std::vector<int> s2 = list2;
std::sort(s1.begin(), s1.end());
std::sort(s2.begin(), s2.end());
int distance = 0;
for (size_t i = 0; i < s1.size(); ++i) {
distance += std::abs(s1[i] - s2[i]);
}
return distance;
}
int compute_similarity(const std::vector<int>& list1, const std::vector<int>& list2) {
std::unordered_map<int, int> right_count;
for (int x : list2) {
right_count[x]++;
}
int similarity = 0;
for (int x : list1) {
similarity += right_count[x] * x;
}
return similarity;
}
int main(int argc, char* argv[]) {
Args args = parse_args(argc, argv);
std::istream* input;
std::ifstream file;
if (args.input_file == "-") {
input = &std::cin;
} else {
file.open(args.input_file);
if (!file) {
std::cerr << "Error opening file: " << args.input_file << std::endl;
return 1;
}
input = &file;
}
try {
auto [list1, list2] = parse_input(*input);
int distance = compute_distance(list1, list2);
int similarity = compute_similarity(list1, list2);
std::cout << "Distance: " << distance << std::endl;
std::cout << "Similarity: " << similarity << std::endl;
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
return 1;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment