#include #include #include #include #include #include #include #include #include char input[] = { #embed "input-.txt" ,'\0' // null terminator }; typedef struct{ uint64_t* divs; int count; int pos_count; } divisors; //char input[] = "L68\nL30\nR48\nL5\nR60\nL55\nL1\nL99\nR14\nL82\n"; int width = 0; int height = 0; uint64_t result = 0; uint64_t result_2 = 0; uint64_t parseNum(char* str, int* len){ int i = 0; uint64_t out = 0; while(str[i] != ',' && str[i] != '-' && str[i] != '\n'){ out += str[i]-0x30; out *= 10; i++; } out /=10; *len = i; return out; } int numPlaces (uint64_t n) { int r = 1; while (n > 9) { n /= 10; r++; } //printf("%d has %d places\n", n, r); return r; } uint64_t power(uint64_t base, uint64_t exp) { uint64_t i, result = 1; for (i = 0; i < exp; i++) result *= base; return result; } uint64_t gen_div(int len, int spacing){ uint64_t div = 0; for(int i = 0; istarts[o]){ curr_min = o; } } uint64_t tmp_start = starts[curr_min]; uint64_t tmp_end = ends[curr_min]; starts[curr_min] = starts[i]; ends[curr_min] = ends[i]; starts[i] = tmp_start; ends[i] = tmp_end; } } //splits ranges that go over a decimal overflow barrier into two (or if necessary more) ranges void optimize_ranges(uint64_t* starts, uint64_t* ends, int* len){ for(int i = 0; i<(*len); i++){ if(numPlaces(starts[i])limit){ return 0; } } return res; } void gen_scms(uint64_t* divs, int* count, int* pos_count){ for(int i = 0; i<*pos_count-1; i++){ for(int o = i+1; i<*pos_count; i++){ uint64_t newdiv = scm(divs[i], divs[o], power(10, numPlaces(divs[i]*2))); if(newdiv!=0){ printf("\t\tfound scm divisor: %lu", newdiv); divs[*count] = newdiv; (*count)++; } } } } divisors* find_divs(int num){ divisors* divs = calloc(sizeof(divisors), 1); divs->divs = calloc(num, sizeof(uint64_t)); printf("\tsearching for natural divisors\n"); for(int i = 2; i<=num; i++){ if(!(num%i)){ uint64_t newdiv = gen_div(i, num/i); printf("\t\tfound %lu natural divisor\n", newdiv); //bool redundant = false; //for(int i = 0; idivs[divs->count] = newdiv; divs->count++; } } printf("\tsearching for scm divisors\n"); gen_scms(divs->divs, &(divs->count), &(divs->pos_count)); return divs; } //4174379265 //4174601487 //4174601487 //4174823709 //4174823709 //4174823709 uint64_t check_range(uint64_t start, uint64_t end){ printf("Range %lu - %lu\n", start, end); int num = numPlaces(start); uint64_t res = 0; printf("Finding Divs:\n"); divisors* divs = find_divs(num); printf("Checking Divs:\n"); for(int i = 0; icount; i++){ uint64_t div = divs->divs[i]; //uint64_t div = gen_div(i, num/i); uint64_t a = ((start+div-1)/div); uint64_t b = (end)/div; //uint64_t sum = sumup(a, b); uint64_t sum = sumup_gauss(a, b); if(ipos_count){ res += sum*div; } else{ res -= sum*div; } printf("div: %lu\nsumup: \t%lu\ncount: \t%lu\n", div, sum*div, res); } printf("=============================================================\n"); free(divs->divs); free(divs); return res; } int main(int argc, char *argv[]){ clock_t start, end; start = clock(); //printf("INT_MAX: %d\n", INT_MAX); int i = 0; int num_ranges = 1; while(input[i] != 0){ if(input[i]==','){ num_ranges++; } i++; } uint64_t starts[num_ranges*2]; uint64_t ends[num_ranges*2]; i = 0; int range_num = 0; int len = 0; while(input[i] != 0){ starts[range_num] = parseNum(&input[i], &len); i+=len+1; ends[range_num] = parseNum(&input[i], &len); i+=len+1; //printf("%d-%d\n", starts[range_num], ends[range_num]); range_num++; } optimize_ranges(starts, ends, &num_ranges); for(i = 0; i