Finally made day 2. I suspect a more elegant solution is possible and it could certainly be more efficient.When run in release mode (-O2)
Code:
#include <iostream>#include <chrono>#include <fstream>#include <set>const char* filename = "data.txt";const int tens[] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};inline bool isodd(int i){ return i & 1;}int digits(long num){ int ret = 0; while(num) { num /= 10; ret++; } return ret;}long checkrange(long r1, long r2, int d, int num, std::set<long>& found){ // check range for repeated patterns of num digits; // r1 and r2 are assumed to have the same number of digits // d is the number of digits in ranges // num is the number of digits of the pattern to check if(d % num) return 0; // s is the number of repeats of the pattern int s = d / num; long ret = 0; int p = tens[num]; long x = 1; // this could be improved while(x < (p * s)) { // make t the repeated pattern long t = x; for(int i = 0; i < s - 1; i++) t = (t * p) + x; // check if repeated pattern is in range if((r1 <= t) && (r2 >= t)) { // avoid duplicates if(found.find(t) == found.cend()) { ret += t; found.insert(t); } } if(t > r2) break; x++; } return ret;}long checkpatterns(long r1, long r2, int digits){ // my data has at most 10 digits // we need to look for sequences of 2,3,4,5 digits // some calls will be invalid but checkrange will sort // set found set stops repeats e.g 11 4 times and 1111 twice long ret = 0; std::set<long> found; for(int p = 1; p <= digits/2; p++) ret += checkrange(r1, r2, digits, p, found); return ret;}long check2(long r1, long r2){ // if neccessary split range so limits have same digits // call checkrange for all possible pattern sizes long ret = 0; int d1 = digits(r1); int d2 = digits(r2); if(d1 != d2) { ret += checkpatterns(r1,tens[d1] -1, d1); ret += checkpatterns(tens[d2 - 1],r2, d2); } else ret += checkpatterns(r1,r2,d1); return ret;}long check1(long r1, long r2){ // some range limits have different number of digits // invalid id must have even number of digits int d1 = digits(r1); int d2 = digits(r2); int d; // r1 and r2 must be even // in my data range limits differ by at most one digit in size if(d1 != d2) { if(isodd(d1)) { r1 = tens[d1]; d = d2; } else { r2 = tens[d2 - 1]; d = d1; } } else d = d1; if(isodd(d)) return 0; // generate numbers ofthe form xyzxyz // and then test if in range; long ret = 0; int p = tens[d/2]; long x = r1 / p; while(x < p) { long t = x + x*p; if(r1 <= t && t <= r2) ret += t; if(t > r2) break; x++; } return ret;}int main(){ std::chrono::time_point<std::chrono::system_clock> start,stop; start = std::chrono::system_clock::now(); std::cout << "Advent of code 2025 day 2 \n"; std::ifstream file(filename); long part1 = 0; long part2 = 0; if(file) { while(!file.eof()) { long l1,l2; char c; file >> l1 >> l2 >> c; //std::cout << l1 << " " << -l2 << " " << digits(-l2) << std::endl; part1 += check1(l1, -l2); part2 += check2(l1, -l2); } } std::cout << "Part 1 " << part1 << "\n"; std::cout << "Part 2 " << part2 << "\n"; stop = std::chrono::system_clock::now(); std::chrono::duration<double> elapsed = stop - start; std::cout << "Elapsed time " << elapsed.count() << " seconds" << "\n"; return 0;}Code:
Advent of code 2025 day 2 Part 1 21139440284Part 2 38731915928Elapsed time 0.000861608 secondsStatistics: Posted by RogerW — Thu Dec 04, 2025 10:47 am