WeixiangYan/CodeTransOcean huggingface dataset:
Task: Untouchable numbers

C: #include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <locale.h>

bool *primeSieve(int limit) {
    int i, p;
    limit++;
    
    bool *c = calloc(limit, sizeof(bool)); 
    c[0] = true;
    c[1] = true;
    for (i = 4; i < limit; i += 2) c[i] = true;
    p = 3; 
    while (true) {
        int p2 = p * p;
        if (p2 >= limit) break;
        for (i = p2; i < limit; i += 2 * p) c[i] = true;
        while (true) {
            p += 2;
            if (!c[p]) break;
        }
    }
    return c;
}

int main() {
    const int limit = 1000000;
    int i, j, n, uc = 2, p = 10, m = 63, ul = 151000;
    bool *c = primeSieve(limit);
    n = m * limit + 1;
    int *sumDivs = (int *)calloc(n, sizeof(int));
    for (i = 1; i < n; ++i) {
        for (j = i; j < n; j += i) sumDivs[j] += i;
    }
    bool *s = (bool *)calloc(n, sizeof(bool)); 
    for (i = 1; i < n; ++i) {
        int sum = sumDivs[i] - i; 
        if (sum <= n) s[sum] = true;
    } 
    free(sumDivs);
    int *untouchable = (int *)malloc(ul * sizeof(int));
    untouchable[0] = 2;
    untouchable[1] = 5;
    for (n = 6; n <= limit; n += 2) {
        if (!s[n] && c[n-1] && c[n-3]) untouchable[uc++] = n;
    }
    setlocale(LC_NUMERIC, "");
    printf("List of untouchable numbers <= 2,000:\n");
    for (i = 0; i < uc; ++i) {
        j = untouchable[i];
        if (j > 2000) break;
        printf("%'6d ", j);
        if (!((i+1) % 10)) printf("\n");
    }
    printf("\n\n%'7d untouchable numbers were found  <=     2,000\n", i);
    for (i = 0; i < uc; ++i) {
        j = untouchable[i];
        if (j > p) {
            printf("%'7d untouchable numbers were found  <= %'9d\n", i, p);
            p *= 10;
            if (p == limit) break;
        }
    }
    printf("%'7d untouchable numbers were found  <= %'d\n", uc, limit);
    free(c);
    free(s);
    free(untouchable);
    return 0;
}
Task: Partition function P

C: #include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <gmp.h>

mpz_t* partition(uint64_t n) {
	mpz_t *pn = (mpz_t *)malloc((n + 2) * sizeof(mpz_t));
	mpz_init_set_ui(pn[0], 1);
	mpz_init_set_ui(pn[1], 1);
	for (uint64_t i = 2; i < n + 2; i ++) {
		mpz_init(pn[i]);
		for (uint64_t k = 1, penta; ; k++) {
			penta = k * (3 * k - 1) >> 1;
			if (penta >= i) break;
			if (k & 1) mpz_add(pn[i], pn[i], pn[i - penta]);
			else mpz_sub(pn[i], pn[i], pn[i - penta]);
			penta += k;
			if (penta >= i) break;
			if (k & 1) mpz_add(pn[i], pn[i], pn[i - penta]);
			else mpz_sub(pn[i], pn[i], pn[i - penta]);
		}
	}
	mpz_t *tmp = &pn[n + 1];
	for (uint64_t i = 0; i < n + 1; i ++) mpz_clear(pn[i]);
	free(pn);
	return tmp;
}

int main(int argc, char const *argv[]) {
	clock_t start = clock();
	mpz_t *p = partition(6666);
	gmp_printf("%Zd\n", p);
	printf("Elapsed time: %.04f seconds\n",
		(double)(clock() - start) / (double)CLOCKS_PER_SEC);
	return 0;
}
Task: Erdős-Nicolas numbers

C: #include <stdio.h>
#include <stdlib.h>

int main() {
    const int maxNumber = 100000000;
    int *dsum = (int *)malloc((maxNumber + 1) * sizeof(int));
    int *dcount = (int *)malloc((maxNumber + 1) * sizeof(int));
    int i, j;
    for (i = 0; i <= maxNumber; ++i) {
        dsum[i] = 1;
        dcount[i] = 1;
    }
    for (i = 2; i <= maxNumber; ++i) {
        for (j = i + i; j <= maxNumber; j += i) {
            if (dsum[j] == j) {
                printf("%8d equals the sum of its first %d divisors\n", j, dcount[j]);
            }
            dsum[j] += i;
            ++dcount[j];
        }
    }
    free(dsum);
    free(dcount);
    return 0;
}
Task: Special divisors

C: #include <stdbool.h>
#include <stdio.h>

int reverse(int n) {
    int result = 0;
    while (n > 0) {
        result = 10 * result + n % 10;
        n /= 10;
    }
    return result;
}

int main() {
    const int limit1 = 200;

    int row = 0;
    int num = 0;
    int n;

    for (n = 1; n < limit1; n++) {
        bool flag = true;
        int revNum = reverse(n);
        int m;

        for (m = 1; m < n / 2; m++) {
            int revDiv = reverse(m);
            if (n % m == 0) {
                if (revNum % revDiv == 0) {
                    flag = true;
                } else {
                    flag = false;
                    break;
                }
            }
        }

        if (flag) {
            num++;
            row++;
            printf("%4d ", n);
            if (row % 10 == 0) {
                printf("\n");
            }
        }
    }

    printf("\n\nFound %d special divisors N that reverse(D) divides reverse(N) for all divisors D of N, where N < 200\n", num);

    return 0;
}
Task: Nimber arithmetic

C: #include <stdio.h>
#include <stdint.h>


uint32_t hpo2(uint32_t n) {
    return n & -n;
}


uint32_t lhpo2(uint32_t n) {
    uint32_t q = 0, m = hpo2(n);
    for (; m % 2 == 0; m >>= 1, ++q) {}
    return q;
}


uint32_t nimsum(uint32_t x, uint32_t y) {
    return x ^ y;
}


uint32_t nimprod(uint32_t x, uint32_t y) {
    if (x < 2 || y < 2)
        return x * y;
    uint32_t h = hpo2(x);
    if (x > h)
        return nimprod(h, y) ^ nimprod(x ^ h, y);
    if (hpo2(y) < y)
        return nimprod(y, x);
    uint32_t xp = lhpo2(x), yp = lhpo2(y);
    uint32_t comp = xp & yp;
    if (comp == 0)
        return x * y;
    h = hpo2(comp);
    return nimprod(nimprod(x >> h, y >> h), 3 << (h - 1));
}

void print_table(uint32_t n, char op, uint32_t(*func)(uint32_t, uint32_t)) {
    printf(" %c |", op);
    for (uint32_t a = 0; a <= n; ++a)
        printf("%3d", a);
    printf("\n--- -");
    for (uint32_t a = 0; a <= n; ++a)
        printf("---");
    printf("\n");
    for (uint32_t b = 0; b <= n; ++b) {
        printf("%2d |", b);
        for (uint32_t a = 0; a <= n; ++a)
            printf("%3d", func(a, b));
        printf("\n");
    }
}

int main() {
    print_table(15, '+', nimsum);
    printf("\n");
    print_table(15, '*', nimprod);
    const uint32_t a = 21508, b = 42689;
    printf("\n%d + %d = %d\n", a, b, nimsum(a, b));
    printf("%d * %d = %d\n", a, b, nimprod(a, b));
    return 0;
}
Task: Double Twin Primes

C: #include <stdio.h>
#include <stdbool.h>

bool isPrime(int n) {
    if (n < 2) return false;
    if (n%2 == 0) return n == 2;
    if (n%3 == 0) return n == 3;
    int d = 5;
    while (d*d <= n) {
        if (n%d == 0) return false;
        d += 2;
        if (n%d == 0) return false;
        d += 4;
    }
    return true;
}

int main() {
    printf("Double twin primes under 1,000:\n");
    for (int i = 3; i < 992; i+=2) {
        if (isPrime(i) && isPrime(i+2) && isPrime(i+6) && isPrime(i+8)) {
            printf("%4d %4d %4d %4d\n", i, i+2, i+6, i+8);
        }
    }    
    return 0;
}
Task: De Polignac numbers

C: #include <stdio.h>
#include <stdbool.h>
#include <locale.h>

bool isPrime(int n) {
    if (n < 2) return false;
    if (n%2 == 0) return n == 2;
    if (n%3 == 0) return n == 3;
    int d = 5;
    while (d*d <= n) {
        if (n%d == 0) return false;
        d += 2;
        if (n%d == 0) return false;
        d += 4;
    }
    return true;
}

int main() {
    int i, j, n, pows2[20], dp[50], dpc = 1, dp1000, dp10000, count, pow;
    bool found;
    for (i = 0; i < 20; ++i) pows2[i] = 1 << i;
    dp[0] = 1;
    for (n = 3, count = 1; count < 10000; n += 2) {
        found = false;
        for (j = 0; j < 20; ++j) {
            pow = pows2[j];
            if (pow > n) break;
            if (isPrime(n-pow)) {
                found = true;
                break;
            }
        }
        if (!found) {
            ++count;
            if (count <= 50) {
                dp[dpc++] = n;
            } else if (count == 1000) {
                dp1000 = n;
            } else if (count == 10000) {
                dp10000 = n;
            }
        }
    }
    setlocale(LC_NUMERIC, "");
    printf("First 50 De Polignac numbers:\n");
    for (i = 0; i < dpc; ++i) {
        printf("%'5d ", dp[i]);
        if (!((i+1)%10)) printf("\n");
    }
    printf("\nOne thousandth: %'d\n", dp1000);
    printf("\nTen thousandth: %'d\n", dp10000);
    return 0;
}
Task: Legendre prime counting function

C: #include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>

const uint8_t masks[8] = {1, 2, 4, 8, 16, 32, 64, 128};

#define half(n) ((int64_t)((n) - 1) >> 1)

#define divide(nm, d) ((uint64_t)((double)nm / (double)d))

int64_t countPrimes(uint64_t n) {
    if (n < 9) return (n < 2) ? 0 : ((int64_t)n + 1) / 2;    
    uint64_t rtlmt = (uint64_t)sqrt((double)n);
    int64_t mxndx = (int64_t)((rtlmt - 1) / 2);
    int arrlen = (int)(mxndx + 1);
    uint32_t *smalls = malloc(arrlen * 4);
    uint32_t *roughs = malloc(arrlen * 4);
    int64_t *larges  = malloc(arrlen * 8);
    for (int i = 0; i < arrlen; ++i) {
        smalls[i] = (uint32_t)i;
        roughs[i] = (uint32_t)(i + i + 1);
        larges[i] = (int64_t)((n/(uint64_t)(i + i + 1) - 1) / 2);
    }
    int cullbuflen = (int)((mxndx + 8) / 8);
    uint8_t *cullbuf = calloc(cullbuflen, 1);
    int64_t nbps = 0;
    int rilmt = arrlen;
    for (int64_t i = 1; ; ++i) {
        int64_t sqri = (i + i) * (i + 1);
        if (sqri > mxndx) break;
        if (cullbuf[i >> 3] & masks[i & 7]) continue;
        cullbuf[i >> 3] |= masks[i & 7];
        uint64_t bp = (uint64_t)(i + i + 1);
        for (int64_t c = sqri; c < (int64_t)arrlen; c += (int64_t)bp) {
            cullbuf[c >> 3] |= masks[c & 7];
        }
        int nri = 0;
        for (int ori = 0; ori < rilmt; ++ori) {
            uint32_t r = roughs[ori];
            int64_t rci = (int64_t)(r >> 1);
            if (cullbuf[rci >> 3] & masks[rci & 7]) continue;
            uint64_t d = (uint64_t)r * bp;
            int64_t t = (d <= rtlmt) ? larges[(int64_t)smalls[d >> 1] - nbps] :
                                       (int64_t)smalls[half(divide(n, d))];
            larges[nri] = larges[ori] - t + nbps;
            roughs[nri] = r;
            nri++;
        }
        int64_t si = mxndx;
        for (uint64_t pm = (rtlmt/bp - 1) | 1; pm >= bp; pm -= 2) {
            uint32_t c = smalls[pm >> 1];
            uint64_t e = (pm * bp) >> 1;
            for ( ; si >= (int64_t)e; --si) smalls[si] -= c - (uint32_t)nbps;                           
        }
        rilmt = nri;
        nbps++;
    }
    int64_t ans = larges[0] + (int64_t)((rilmt + 2*(nbps - 1)) * (rilmt - 1) / 2);
    int ri, sri;
    for (ri = 1; ri < rilmt; ++ri) ans -= larges[ri];
    for (ri = 1; ; ++ri) {
        uint64_t p = (uint64_t)roughs[ri];
        uint64_t m = n / p;
        int ei = (int)smalls[half((uint64_t)m/p)] - nbps;
        if (ei <= ri) break;
        ans -= (int64_t)((ei - ri) * (nbps + ri - 1));
        for (sri = ri + 1; sri < ei + 1; ++sri) {
            ans += (int64_t)smalls[half(divide(m, (uint64_t)roughs[sri]))];
        }
    }
    free(smalls);
    free(roughs);
    free(larges);
    free(cullbuf);
    return ans + 1;
}

int main() {
    uint64_t n;
    int i;
    clock_t start = clock();
    for (i = 0, n = 1; i < 10; ++i, n *= 10) {
        printf("10^%d %ld\n", i, countPrimes(n));
    }
    clock_t end = clock();
    printf("\nTook %f seconds\n", (double) (end - start) / CLOCKS_PER_SEC);
    return 0;
}
Task: Permuted multiples

C: #include <stdio.h>
#include <stdbool.h>


int digit_set(int n) {
    static const int powers[] = {
        1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
        100000000, 1000000000
    };
    
    int dset;
    for (dset = 0; n; n /= 10)
        dset += powers[n % 10];
    return dset;
}


bool is_permuted_multiple(int n) {
    int dset = digit_set(n);
    for (int mult = 2; mult <= 6; mult++)
        if (dset != digit_set(n * mult)) return false;
    return true;
}


int main() {
    int n;
    for (n = 123; !is_permuted_multiple(n); n++);
    for (int mult = 1; mult <= 6; mult++)
        printf("%d * n = %d\n", mult, n*mult);
    return 0;
}
Task: Chernick's Carmichael numbers

C: #include <stdio.h>
#include <stdlib.h>
#include <gmp.h>

typedef unsigned long long int u64;

#define TRUE 1
#define FALSE 0

int primality_pretest(u64 k) {
    if (!(k %  3) || !(k %  5) || !(k %  7) || !(k % 11) || !(k % 13) || !(k % 17) || !(k % 19) || !(k % 23)) return (k <= 23);
    return TRUE;
}

int probprime(u64 k, mpz_t n) {
    mpz_set_ui(n, k);
    return mpz_probab_prime_p(n, 0);
}

int is_chernick(int n, u64 m, mpz_t z) {
    u64 t = 9 * m;
    if (primality_pretest(6 * m + 1) == FALSE) return FALSE;
    if (primality_pretest(12 * m + 1) == FALSE) return FALSE;
    for (int i = 1; i <= n - 2; i++) if (primality_pretest((t << i) + 1) == FALSE) return FALSE;
    if (probprime(6 * m + 1, z) == FALSE) return FALSE;
    if (probprime(12 * m + 1, z) == FALSE) return FALSE;
    for (int i = 1; i <= n - 2; i++) if (probprime((t << i) + 1, z) == FALSE) return FALSE;
    return TRUE;
}

int main(int argc, char const *argv[]) {
    mpz_t z;
    mpz_inits(z, NULL);

    for (int n = 3; n <= 10; n ++) {
        u64 multiplier = (n > 4) ? (1 << (n - 4)) : 1;

        if (n > 5) multiplier *= 5;

        for (u64 k = 1; ; k++) {
            u64 m = k * multiplier;

            if (is_chernick(n, m, z) == TRUE) {
                printf("a(%d) has m = %llu\n", n, m);
                break;
            }
        }
    }

    return 0;
}
Task: The sieve of Sundaram

C: #include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void) {
    int nprimes =  1000000;
    int nmax =    ceil(nprimes*(log(nprimes)+log(log(nprimes))-0.9385));  
      
      
    int i, j, m, k; int *a;
    k = (nmax-2)/2; 
    a = (int *)calloc(k + 1, sizeof(int));
    for(i = 0; i <= k; i++)a[i] = 2*i+1; 
    for (i = 1; (i+1)*i*2 <= k; i++)
        for (j = i; j <= (k-i)/(2*i+1); j++) {
            m = i + j + 2*i*j;
            if(a[m]) a[m] = 0;
            }            
        
    for (i = 1, j = 0; i <= k; i++) 
       if (a[i]) {
           if(j%10 == 0 && j <= 100)printf("\n");
           j++; 
           if(j <= 100)printf("%3d ", a[i]);
           else if(j == nprimes){
               printf("\n%d th prime is %d\n",j,a[i]);
               break;
               }
           }
}
Task: Consecutive primes with ascending or descending differences

C: #include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

bool *sieve(int limit) {
    int i, p;
    limit++;
    
    bool *c = calloc(limit, sizeof(bool)); 
    c[0] = true;
    c[1] = true;
    for (i = 4; i < limit; i += 2) c[i] = true;
    p = 3; 
    while (true) {
        int p2 = p * p;
        if (p2 >= limit) break;
        for (i = p2; i < limit; i += 2 * p) c[i] = true;
        while (true) {
            p += 2;
            if (!c[p]) break;
        }
    }
    return c;
}

void longestSeq(int *primes, int pc, bool asc) {
    int i, j, d, pd = 0, lls = 1, lcs = 1;
    int longSeqs[25][10] = {{2}};
    int lsl[25] = {1};
    int currSeq[10] = {2};
    const char *dir = asc ? "ascending" : "descending";
    for (i = 1; i < pc; ++i) {
        d = primes[i] - primes[i-1];
        if ((asc && d <= pd) || (!asc && d >= pd)) {
            if (lcs > lsl[0]) {
                memcpy((void *)longSeqs[0], (void *)currSeq, lcs * sizeof(int));
                lsl[0] = lcs;
                lls = 1;
            } else if (lcs == lsl[0]) {
                memcpy((void *)longSeqs[lls], (void *)currSeq, lcs * sizeof(int));
                lsl[lls++] = lcs;
            }
            currSeq[0] = primes[i-1];
            currSeq[1] = primes[i];
            lcs = 2;
        } else {
            currSeq[lcs++] = primes[i];
        }
        pd = d;
    }
    if (lcs > lsl[0]) {
        memcpy((void *)longSeqs[0], (void *)currSeq, lcs * sizeof(int));
        lsl[0] = lcs;
        lls = 1;
    } else if (lcs == lsl[0]) {
        memcpy((void *)longSeqs[lls], (void *)currSeq, lcs * sizeof(int));
        lsl[lls++] = lcs;
    }
    printf("Longest run(s) of primes with %s differences is %d:\n", dir, lsl[0]);
    for (i = 0; i < lls; ++i) {
        int *ls = longSeqs[i];
        for (j = 0; j < lsl[i]-1; ++j) printf("%d (%d) ", ls[j], ls[j+1] - ls[j]);
        printf("%d\n", ls[lsl[i]-1]);
    }
    printf("\n");
}

int main() {
    const int limit = 999999;
    int i, j, pc = 0;
    bool *c = sieve(limit);
    for (i = 0; i < limit; ++i) {
        if (!c[i]) ++pc;
    }
    int *primes = (int *)malloc(pc * sizeof(int));
    for (i = 0, j = 0; i < limit; ++i) {
        if (!c[i]) primes[j++] = i;
    }
    free(c);
    printf("For primes < 1 million:\n");
    longestSeq(primes, pc, true);
    longestSeq(primes, pc, false);
    free(primes);
    return 0;
}
Task: Verhoeff algorithm

C: #include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

static const int d[][10] = {
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, {1, 2, 3, 4, 0, 6, 7, 8, 9, 5},
    {2, 3, 4, 0, 1, 7, 8, 9, 5, 6}, {3, 4, 0, 1, 2, 8, 9, 5, 6, 7},
    {4, 0, 1, 2, 3, 9, 5, 6, 7, 8}, {5, 9, 8, 7, 6, 0, 4, 3, 2, 1},
    {6, 5, 9, 8, 7, 1, 0, 4, 3, 2}, {7, 6, 5, 9, 8, 2, 1, 0, 4, 3},
    {8, 7, 6, 5, 9, 3, 2, 1, 0, 4}, {9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
};

static const int inv[] = {0, 4, 3, 2, 1, 5, 6, 7, 8, 9};

static const int p[][10] = {
    {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, {1, 5, 7, 6, 2, 8, 3, 0, 9, 4},
    {5, 8, 0, 3, 7, 9, 6, 1, 4, 2}, {8, 9, 1, 6, 0, 4, 3, 5, 2, 7},
    {9, 4, 5, 3, 1, 2, 6, 8, 7, 0}, {4, 2, 8, 6, 5, 7, 3, 9, 0, 1},
    {2, 7, 9, 3, 8, 0, 6, 4, 1, 5}, {7, 0, 4, 6, 9, 1, 3, 2, 5, 8},
};

int verhoeff(const char* s, bool validate, bool verbose) {
    if (verbose) {
        const char* t = validate ? "Validation" : "Check digit";
        printf("%s calculations for '%s':\n\n", t, s);
        puts(u8" i  n\xE1\xB5\xA2  p[i,n\xE1\xB5\xA2]  c");
        puts("------------------");
    }
    int len = strlen(s);
    if (validate)
        --len;
    int c = 0;
    for (int i = len; i >= 0; --i) {
        int ni = (i == len && !validate) ? 0 : s[i] - '0';
        assert(ni >= 0 && ni < 10);
        int pi = p[(len - i) % 8][ni];
        c = d[c][pi];
        if (verbose)
            printf("%2d  %d      %d     %d\n", len - i, ni, pi, c);
    }
    if (verbose && !validate)
        printf("\ninv[%d] = %d\n", c, inv[c]);
    return validate ? c == 0 : inv[c];
}

int main() {
    const char* ss[3] = {"236", "12345", "123456789012"};
    for (int i = 0; i < 3; ++i) {
        const char* s = ss[i];
        bool verbose = i < 2;
        int c = verhoeff(s, false, verbose);
        printf("\nThe check digit for '%s' is '%d'.\n", s, c);
        int len = strlen(s);
        char sc[len + 2];
        strncpy(sc, s, len + 2);
        for (int j = 0; j < 2; ++j) {
            sc[len] = (j == 0) ? c + '0' : '9';
            int v = verhoeff(sc, true, verbose);
            printf("\nThe validation for '%s' is %s.\n", sc,
                   v ? "correct" : "incorrect");
        }
    }
    return 0;
}
Task: Padovan n-step number sequences

C: #include <stdio.h>

void padovanN(int n, size_t t, int *p) {
    int i, j;
    if (n < 2 || t < 3) {
        for (i = 0; i < t; ++i) p[i] = 1;
        return;
    }
    padovanN(n-1, t, p);
    for (i = n + 1; i < t; ++i) {
        p[i] = 0;
        for (j = i - 2; j >= i - n - 1; --j) p[i] += p[j];
    }
}

int main() {
    int n, i;
    const size_t t = 15;
    int p[t];
    printf("First %ld terms of the Padovan n-step number sequences:\n", t);
    for (n = 2; n <= 8; ++n) {
        for (i = 0; i < t; ++i) p[i] = 0;
        padovanN(n, t, p);
        printf("%d: ", n);
        for (i = 0; i < t; ++i) printf("%3d ", p[i]);
        printf("\n");
    }
    return 0;
}
Task: Prime triangle

C: #include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <time.h>

bool is_prime(unsigned int n) {
    assert(n < 64);
    static bool isprime[] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0,
                             0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1,
                             0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1,
                             0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0};
    return isprime[n];
}

void swap(unsigned int* a, size_t i, size_t j) {
    unsigned int tmp = a[i];
    a[i] = a[j];
    a[j] = tmp;
}

bool prime_triangle_row(unsigned int* a, size_t length) {
    if (length == 2)
        return is_prime(a[0] + a[1]);
    for (size_t i = 1; i + 1 < length; i += 2) {
        if (is_prime(a[0] + a[i])) {
            swap(a, i, 1);
            if (prime_triangle_row(a + 1, length - 1))
                return true;
            swap(a, i, 1);
        }
    }
    return false;
}

int prime_triangle_count(unsigned int* a, size_t length) {
    int count = 0;
    if (length == 2) {
        if (is_prime(a[0] + a[1]))
            ++count;
    } else {
        for (size_t i = 1; i + 1 < length; i += 2) {
            if (is_prime(a[0] + a[i])) {
                swap(a, i, 1);
                count += prime_triangle_count(a + 1, length - 1);
                swap(a, i, 1);
            }
        }
    }
    return count;
}

void print(unsigned int* a, size_t length) {
    if (length == 0)
        return;
    printf("%2u", a[0]);
    for (size_t i = 1; i < length; ++i)
        printf(" %2u", a[i]);
    printf("\n");
}

int main() {
    clock_t start = clock();
    for (unsigned int n = 2; n < 21; ++n) {
        unsigned int a[n];
        for (unsigned int i = 0; i < n; ++i)
            a[i] = i + 1;
        if (prime_triangle_row(a, n))
            print(a, n);
    }
    printf("\n");
    for (unsigned int n = 2; n < 21; ++n) {
        unsigned int a[n];
        for (unsigned int i = 0; i < n; ++i)
            a[i] = i + 1;
        if (n > 2)
            printf(" ");
        printf("%d", prime_triangle_count(a, n));
    }
    printf("\n");
    clock_t end = clock();
    double duration = (end - start + 0.0) / CLOCKS_PER_SEC;
    printf("\nElapsed time: %f seconds\n", duration);
    return 0;
}
Task: Honaker primes

C: #include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <locale.h>

#define LIMIT 5000000

typedef struct {
    int x;
    int y;
} pair;

int *primeSieve(int limit, int *length) {
    int i, p, *primes;
    int j, pc = 0;
    limit++;
    
    bool *c = calloc(limit, sizeof(bool)); 
    c[0] = true;
    c[1] = true;
    for (i = 4; i < limit; i += 2) c[i] = true;
    p = 3; 
    while (true) {
        int p2 = p * p;
        if (p2 >= limit) break;
        for (i = p2; i < limit; i += 2 * p) c[i] = true;
        while (true) {
            p += 2;
            if (!c[p]) break;
        }
    }
    for (i = 0; i < limit; ++i) {
        if (!c[i]) ++pc;
    }
    primes = (int *)malloc(pc * sizeof(int));
    for (i = 0, j = 0; i < limit; ++i) {
        if (!c[i]) primes[j++] = i;
    }
    free(c);
    *length = pc;
    return primes;
}

int digitSum(int n) {
    int sum = 0;
    while (n > 0) {
        sum += n % 10;
        n /= 10;
    }
    return sum;
}

int main() {
    int i, count, length, hc = 0;
    int *primes = (int *)primeSieve(LIMIT, &length);
    pair h[50], h10000;
    for (i = 1, count = 0; count < 10000; ++i) {
        if (digitSum(i) == digitSum(primes[i-1])) {
            ++count;
            if (count <= 50) {
                h[hc++] = (pair){i, primes[i-1]};
            } else if (count == 10000) {
                h10000.x = i;
                h10000.y = primes[i-1];
            }
        }
    }
    setlocale(LC_NUMERIC, "");
    printf("The first 50 Honaker primes (index, prime):\n");
    for (i = 0; i < 50; ++i) {
        printf("(%3d, %'5d) ", h[i].x, h[i].y);
        if (!((i+1)%5)) printf("\n");
    }
    printf("\nand the 10,000th: (%'7d, %'9d)\n", h10000.x, h10000.y);
    free(primes);
    return 0;
}