Smarandache prime-digital sequence: Difference between revisions

Content added Content deleted
(Added C solution)
Line 175: Line 175:
1-25: 2 3 5 7 23 37 53 73 223 227 233 257 277 337 353 373 523 557 577 727 733 757 773 2237 2273
1-25: 2 3 5 7 23 37 53 73 223 227 233 257 277 337 353 373 523 557 577 727 733 757 773 2237 2273
100: 33223
100: 33223
</pre>

=={{header|C}}==
{{trans|C++}}
<lang c>#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct bit_array_tag {
uint32_t size;
uint32_t* array;
} bit_array;

bool bit_array_create(bit_array* b, uint32_t size) {
uint32_t* array = calloc((size + 31)/32, sizeof(uint32_t));
if (array == NULL)
return false;
b->size = size;
b->array = array;
return true;
}

void bit_array_destroy(bit_array* b) {
free(b->array);
b->array = NULL;
}

void bit_array_set(bit_array* b, uint32_t index, bool value) {
assert(index < b->size);
uint32_t* p = &b->array[index >> 5];
uint32_t bit = 1 << (index & 31);
if (value)
*p |= bit;
else
*p &= ~bit;
}

bool bit_array_get(const bit_array* b, uint32_t index) {
assert(index < b->size);
uint32_t* p = &b->array[index >> 5];
uint32_t bit = 1 << (index & 31);
return (*p & bit) != 0;
}

typedef struct sieve_tag {
uint32_t limit;
bit_array not_prime;
} sieve;

bool sieve_create(sieve* s, uint32_t limit) {
if (!bit_array_create(&s->not_prime, limit + 1))
return false;
bit_array_set(&s->not_prime, 0, true);
bit_array_set(&s->not_prime, 1, true);
for (uint32_t p = 2; p * p <= limit; ++p) {
if (bit_array_get(&s->not_prime, p) == false) {
for (size_t q = p * p; q <= limit; q += p)
bit_array_set(&s->not_prime, q, true);
}
}
s->limit = limit;
return true;
}

void sieve_destroy(sieve* s) {
bit_array_destroy(&s->not_prime);
}

bool is_prime(const sieve* s, uint32_t n) {
assert(n <= s->limit);
return bit_array_get(&s->not_prime, n) == false;
}

uint32_t next_prime_digit_number(uint32_t n) {
if (n == 0)
return 2;
switch (n % 10) {
case 2:
return n + 1;
case 3:
case 5:
return n + 2;
default:
return 2 + next_prime_digit_number(n/10) * 10;
}
}

int main() {
const uint32_t limit = 10000000;
sieve s = { 0 };
if (!sieve_create(&s, limit)) {
fprintf(stderr, "Out of memory\n");
return 1;
}
uint32_t n = 0, n1 = 0, n2 = 0, n3 = 0;
printf("First 25 SPDS primes:\n");
for (int i = 0; ; ) {
n = next_prime_digit_number(n);
if (n >= limit)
break;
if (is_prime(&s, n)) {
if (i < 25) {
if (i > 0)
printf(", ");
printf("%u", n);
}
else if (i == 25)
printf("\n");
++i;
if (i == 100)
n1 = n;
else if (i == 1000)
n2 = n;
n3 = n;
}
}
sieve_destroy(&s);
printf("Hundredth SPDS prime: %u\n", n1);
printf("Thousandth SPDS prime: %u\n", n2);
printf("Largest SPDS prime less than %u: %u\n", limit, n3);
return 0;
}</lang>

{{out}}
<pre>
First 25 SPDS primes:
2, 3, 5, 7, 23, 37, 53, 73, 223, 227, 233, 257, 277, 337, 353, 373, 523, 557, 577, 727, 733, 757, 773, 2237, 2273
Hundredth SPDS prime: 33223
Thousandth SPDS prime: 3273527
Largest SPDS prime less than 10000000: 7777753
</pre>
</pre>