#include #include #include #include #include #include "hash.h" using namespace std; struct Node { unsigned long long value; Node *next; }; Node *parseList(const char *path) { ifstream input(path); string line; getline(input, line); stringstream ss; ss << line; unsigned long long a; // head ss >> a; Node *curr = new Node(); curr->value = a; Node *head = curr; // rest while (ss >> a) { Node *prev = curr; curr = new Node(); curr->value = a; prev->next = curr; } return head; } void blink(Node *head) { Node *curr = head; while (curr != nullptr) { // get next already, to skip newly appended elements Node *next = curr->next; // do blink string num = to_string(curr->value); if (curr->value == 0) { curr->value = 1; } else if (num.size() % 2 == 0) { string num1 = num.substr(0, num.size() / 2); string num2 = num.substr(num.size() / 2, num.size() / 2); Node *new_node = new Node(); curr->value = stol(num1); curr->next = new_node; new_node->value = stol(num2); new_node->next = next; } else { curr->value = curr->value * 2024; } curr = next; } } int length(Node *head) { int ret = 0; Node *curr = head; while (curr != nullptr) { ret++; curr = curr->next; } return ret; } void printList(Node *head) { Node *curr = head; while (curr != nullptr) { cout << curr->value << " "; curr = curr->next; } cout << endl; } // highly inefficient int part1(const char *path) { Node *head = parseList(path); for (int i = 0; i < 25; i++) { blink(head); } return length(head); } unordered_map, long> memo; unsigned long long doBlinks(unsigned long long value, int iterations) { if (iterations == 0) { return 1; } // cache hit if (memo.count(make_tuple(value, iterations))) { // return memo.at(make_tuple(value, iterations)); return memo[make_tuple(value, iterations)]; } // cache miss -> do blink if (value == 0) { long ret = doBlinks(1 , iterations - 1); memo[make_tuple(value, iterations)] = ret; // memo.insert(make_pair(make_tuple(value, iterations), ret)); return ret; } unsigned long long ret = 0; string num = to_string(value); if (num.size() % 2 == 0) { string num1 = num.substr(0, num.size() / 2); string num2 = num.substr(num.size() / 2, num.size() / 2); ret += doBlinks(stol(num1), iterations - 1); ret += doBlinks(stol(num2), iterations - 1); memo[make_tuple(value, iterations)] = ret; return ret; } else { long ret = doBlinks(value * 2024, iterations - 1); memo[make_tuple(value, iterations)] = ret; return ret; } } unsigned long long part2(const char *path) { Node *head = parseList(path); unsigned long long sum = 0; while (head != nullptr) { sum += doBlinks(head->value, 75); head = head->next; } return sum; } int main(int argc, char *argv[]) { cout << "example1: " << part1("example") << endl; cout << "input1: " << part1("input") << endl; cout << "example2: " << part2("example") << endl; cout << "input2: " << part2("input") << endl; return 0;; }