bignum_t * bignum_add (const bignum_t * a, const bignum_t * b) { bignum_t * c = bignum_get (0); if (a->sign == b->sign) { c->sign = a->sign; } else { int cmp = bignum_magnitude_cmp (a, b); if (cmp > 0) { bignum_delete (c); c = bignum_sub_aux (a, b); if (a->sign) c->sign = true; } else if (cmp < 0) { bignum_delete (c); c = bignum_sub_aux (b, a); if (b->sign) c->sign = true; } return c; } size_t used = MAX (a->used, b->used); if (used == 0) return c; else c->used = 0; int carry = 0; int partial_sum = 0; for (size_t i = 0; i < used; i++) { ensure_allocation (c); partial_sum = 0; if (a->used > i) partial_sum += a->digits[i]; if (b->used > i) partial_sum += b->digits[i]; partial_sum += carry; c->digits[c->used++] = partial_sum % 10; carry = partial_sum / 10; } if (carry) { ensure_allocation (c); c->digits[c->used++] = carry; } return c; }
int main (int argc, char ** argv) { if (argc != 2) { fprintf (stderr, "usage: %s <N>\n", argv[0]); return 1; } int N = atoi (argv[1]); if (N < 2) return 1; bignum_t * powers[(N - 1) * (N - 1)]; size_t powers_count = 0; bool * primes = eratosthenes_sieve (N + 1); for (int a = 2; a <= N; a++) { bignum_t * power = NULL; for (int b = 2; b <= N; b++) { bignum_t * new_power = NULL; if (!power) new_power = bignum_get (a * a); else new_power = bignum_mult (power, a); if (b == 2) bignum_delete (power); int duplicate_at = -1; // Powers of a prime base cannot be duplicates if (!primes[a]) for (size_t i = 0; i < powers_count; i++) if (bignum_cmp (powers[i], new_power) == 0) { duplicate_at = i; break; } if (duplicate_at == -1) { powers[powers_count++] = new_power; power = new_power; } else { bignum_delete (new_power); power = powers[duplicate_at]; } } } printf ("%d\n", (int) powers_count); bignum_free_array (powers, powers_count); free (primes); return 0; }
bignum_t * bignum_add_to_ (bignum_t * a, bignum_t * b, bool clear_flag) { bignum_t * c = bignum_add (a, b); bignum_delete (a); if (clear_flag) bignum_delete (b); return c; }
bignum_t * bignum_mult_bignum_to (bignum_t * a, bignum_t * b) { bignum_t * c = bignum_mult (a, b); bignum_delete (a); return c; }
int bignum_is_lychrel(const bignum *a, int tries) { bignum *b, *c; int i, result = 1; b = bignum_copy(a); for (i = 0; i < tries; i++) { c = bignum_copy(b); bignum_reverse_digits(b); bignum_add(b, c); bignum_delete(c); if (bignum_is_palindrome(b)) { result = 0; break; } } bignum_delete(b); return result; }
bignum_t * bignum_mult_int (const bignum_t * a, int b) { bignum_t * bb = bignum_get (b); bignum_t * c = bignum_mult (a, bb); bignum_delete (bb); return c; }
int main (void) { bignum_t * prime = bignum_pow (2, 7830457, DIGITS_TO_CONSIDER); prime = bignum_mult_to (prime, 28433); prime = bignum_add_to (prime, bignum_get (1)); prime->used = DIGITS_TO_CONSIDER; bignum_print (prime); bignum_delete (prime); return 0; }
int main(int argc, const char *argv[]) { int a, count; bignum *big_a; count = 0; for (a = 1; a <= 10000; a++) { big_a = bignum_new(a); if (bignum_is_lychrel(big_a, 50)) { count++; } bignum_delete(big_a); } printf("%d\n", count); return 0; }