unsigned has_same_digits(unsigned a, unsigned b) { unsigned digs = n_digits(a); if (digs == n_digits(b)) { unsigned digits[10] = {0}; unsigned i; for (i=0;i<digs;i++) digits[nth_digit(a,i)]++; for (i=0;i<digs;i++) { if (digits[nth_digit(b,i)] == 0) return 0; } return 1; } return 0; }
/* Returns true if sequence reaches 89. Caches answers for efficiency */ bool reaches_89(long num) { if(num == 1) return false; if(num == 89) return true; if(num < CACHE_LIMIT && cache[num] != -1) return (cache[num] == 1) ? true : false; char num_s[n_digits(num)+1]; sprintf(num_s, "%ld", num); long square_sum = 0; for(int i = 0; i < n_digits(num); i++) { int digit = num_s[i] - '0'; square_sum += digit*digit; } //printf("-> %ld ", square_sum); bool ans = reaches_89(square_sum); if(num < CACHE_LIMIT) { cache[num] = ans; } return ans; }
/* Returns true if and only if the number is pandigital */ bool is_pandigital(long long num) { int digits = n_digits(num); //there can't exist a 10-digit or greater pandigital number if(digits > 9) return false; char num_s[digits + 1]; sprintf(num_s, "%lld", num); //the index 0 is true because the number can't contain a 0 digit bool digit_used[] = {true, false, false, false, false, false, false, false, false, false}; for(int i = 0; i < digits; i++) { int curr_digit = num_s[i] - '0'; if(digit_used[curr_digit] || curr_digit > digits) { return false; } digit_used[curr_digit] = true; } return true; }
int main(void) { unsigned i,c = 0; for (i=2;i<1000000;i++) { if (is_prime(i)) { unsigned len = n_digits(i); unsigned char discard = 0; unsigned j,tmp = i; for (j=1;j<len;j++) { tmp = (tmp/10) + (tmp%10) * ceil(pow(10,floor(log10(tmp)))); if (is_prime(tmp) == 0) { discard = 1; break; } } if (discard==0) c++; } } printf("%u\n",c); return 0; }