4coder-non-source/test_data/lots_of_files/highly_divisible_triangular...

229 lines
4.1 KiB
C++

/*
* YOUR INFO HERE!
*/
// FINAL VERSION:
typedef unsigned long long bigint;
struct Sieve_Array{
bool *is_composite;
bigint size;
};
struct Primes{
bigint *primes;
int count, max;
};
struct Sieve{
Sieve_Array sieve;
Primes ps;
int i;
int w;
};
void extend_sieve(Primes ps, Sieve_Array sieve, int start){
int q,p,j,n,m;
for (q = 1; q < ps.count; ++q){
p = ps.primes[q];
j = start;
n = 2*j + 3;
m = (n/p)*p;
if (n != m){
n = m+p;
if (n % 2 == 0){
n += p;
}
j = (n-3)/2;
}
for (; j < sieve.size; j += p){
sieve.is_composite[j] = 1;
}
}
}
int sieve_partial(Primes *ps_, Sieve_Array sieve, int start){
Primes ps = *ps_;
int i=start,n,j;
for (; i < sieve.size; ++i){
if (!sieve.is_composite[i]){
n = i*2 + 3;
ps.primes[ps.count++] = n;
for (j = i + n; j < sieve.size; j += n){
sieve.is_composite[j] = 1;
}
if (ps.count == ps.max){
++i;
break;
}
}
}
ps_->count = ps.count;
return i;
}
// size of primes >= which_prime
// size of sieve >= size > 0
void begin_sieve(Sieve *s, int prime_size, int size){
s->sieve.size = size;
s->ps.count = 1;
s->ps.max = prime_size;
s->ps.primes[0] = 2;
s->i = 0;
s->w = prime_size;
}
inline bool sieve_step(Sieve *s){
s->i = sieve_partial(&s->ps, s->sieve, s->i);
return (s->ps.count != s->w);
}
inline void sieve_grow(Sieve *s, Sieve_Array new_sieve){
extend_sieve(s->ps, new_sieve, s->sieve.size);
s->sieve = new_sieve;
}
inline int sieve_init_size(int which_prime){
return which_prime*5;
}
inline int sieve_new_size(Sieve s){
return s.sieve.size + s.w * (1 + ((s.w - s.ps.count) / 1000));
}
#ifdef EULER_PROBLEM
// BUILDING AREA:
struct Euler_In{};
struct Euler_Result{
int number;
};
int count_divisors(int x, int *d, Primes ps){
int dc = 0;
int c,p,i,j;
p = ps.primes[0];
for (i = 0; i < ps.count && p < x; ++i){
p = ps.primes[i];
c = 1;
while (x % p == 0){
x /= p;
++c;
}
if (c > 1){
d[dc++] = c;
}
}
c = 1;
for (j = 0; j < dc; ++j){
c *= d[j];
}
return c;
}
int count_divisors(int x, int *d){
int dc = 0;
int c,p,j;
c = 1;
while (x % 2 == 0){
x /= 2;
++c;
}
if (c > 1){
d[dc++] = c;
}
for (p = 3; p <= x; p += 2){
c = 1;
while (x % p == 0){
x /= p;
++c;
}
if (c > 1){
d[dc++] = c;
}
}
c = 1;
for (j = 0; j < dc; ++j){
c *= d[j];
}
return c;
}
inline Euler_Result euler_main(Euler_In in){
int d[500];
int max = 1600;
int *divs = (int*)malloc(sizeof(int)*max);
divs[0] = 0;
divs[1] = 1;
divs[2] = 2;
int x=1,n=2,c=0,a,b;
a=1;
b=1;
while (1){
if (c >= 500){
break;
}
++n;
divs[n] = count_divisors(n, d);
b += 2;
x += 2*a;
c = divs[a]*divs[b];
if (c >= 500){
break;
}
++n;
if (n >= max){
int new_max = max*2;
int *new_divs = (int*)malloc(sizeof(int)*new_max);
memcpy(new_divs, divs, sizeof(int)*max);
free(divs);
divs = new_divs;
max = new_max;
}
divs[n] = count_divisors(n, d);
a += 1;
x += b;
c = divs[a]*divs[b];
}
Euler_Result result;
result.number = x;
return result;
}
void euler_print(Euler_Result answer, Euler_In in){
printf("%d\n", answer.number);
}
#define EULER_CHECK
bool euler_check(Euler_Result answer, Euler_In in){
bool result;
int a = 76576500;
printf("answer = %d\n", a);
result = (a == answer.number);
return result;
}
#endif