Last active
January 12, 2024 13:43
-
-
Save imaami/2e590a64e4dcb1da547e197365524ed8 to your computer and use it in GitHub Desktop.
Check for stringy primes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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