Skip to content

Instantly share code, notes, and snippets.

@imaami
Last active January 12, 2024 13:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save imaami/2e590a64e4dcb1da547e197365524ed8 to your computer and use it in GitHub Desktop.
Save imaami/2e590a64e4dcb1da547e197365524ed8 to your computer and use it in GitHub Desktop.
Check for stringy primes
/* SPDX-License-Identifier: GPL-2.0-or-later */
/**
* @file stringy_check.c
* @author Juuso Alasuutari
*
* @brief Parse the raw content bytes of text strings as if the strings were
* arbitrarily large integers, and check if the result is a different
* prime number in both the big- and little-endian byte orders.
*
* I call the group of primes generated by this method "stringy primes"; run
* `./stringy_check stringy` to see why.
*
* Link with "-lgmp".
*/
#include <gmp.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void
usage (char const *argv0,
int ret)
{
fprintf(stderr, "Usage: %s [-r REPS] STRING...\n"
" %s -h\n", argv0, argv0);
exit(ret);
}
int
main (int argc,
char **argv)
{
int options_end = argc;
int input_count = 0;
int reps = 100;
for (int i = 0; ++i < argc; ) {
char *s = argv[i];
if (i >= options_end || s[0] != '-') {
++input_count;
continue;
}
switch (s[1]) {
case '-':
if (!s[2]) {
options_end = i + 1;
continue;
}
break;
case 'h':
if (s[2])
break;
usage(argv[0], EXIT_SUCCESS);
case 'r':
if (s[2])
s += 2;
else if (++i >= argc || !*(s = argv[i]))
break;
char *end = s;
long n = strtol(s, &end, 0);
if (*end || n < 0 || n > INT_MAX)
break;
reps = (int)n;
continue;
}
input_count = -input_count;
break;
}
if (input_count < 1)
usage(argv[0], EXIT_FAILURE);
mpz_t le, be;
mpz_init(le);
mpz_init(be);
for (int i = 0; ++i < argc; ) {
char const *s = argv[i];
if (i < options_end && s[0] == '-')
// option
continue;
if (!*s)
// empty string
continue;
size_t n = strlen(&s[1]), k = n, j = 0;
for (; j < k && s[j] == s[k]; ++j, --k) {}
if (j >= k)
// byte-level palindrome
continue;
n++;
mpz_import(le, 1U, -1, n, -1, 0, argv[i]);
int lp = mpz_probab_prime_p(le, reps) & 3;
if (!lp)
// definitely not prime in little-endian
continue;
mpz_import(be, 1U, -1, n, 1, 0, argv[i]);
int bp = mpz_probab_prime_p(be, reps) & 3;
if (!bp)
// definitely not prime in big-endian
continue;
printf("%s\t", argv[i]);
mpz_out_str(stdout, 10, le);
putchar('\t');
mpz_out_str(stdout, 10, be);
printf("\t%c%c\n", "npyy"[lp], "npyy"[bp]);
}
mpz_clear(le);
mpz_clear(be);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment