Created
February 25, 2020 16:48
-
-
Save ForeverZer0/bb731cbac821ecd0a8bbfe72dfb9c3f6 to your computer and use it in GitHub Desktop.
Prime number generator
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
#include <stdio.h> | |
#include <getopt.h> | |
#include <string.h> | |
#include <stdint.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
static struct option prime_opts[] = | |
{ | |
{"count", required_argument, NULL, 'c'}, | |
{"number", required_argument, NULL, 'n'}, | |
{"range", required_argument, NULL, 'r'}, | |
{"test", required_argument, NULL, 't'}, | |
{"help", no_argument, NULL, 'h'}, | |
{NULL, 0, NULL, 0} | |
}; | |
static bool is_prime(int64_t n, int64_t *factor) { | |
// Only positive numbers greater than or equal to 2 can be prime | |
if (n < 2) { | |
return false; | |
} | |
// 2 is the only even number that is prime, so check if number is even for an early out | |
if (n % 2 == 0) | |
{ | |
if (factor) *factor = 2; | |
return n == 2; | |
} | |
// Search for a factor, returning first one found | |
int64_t i; | |
for (i = 3; i * i <= n; i += 2) { | |
if (n % i == 0){ | |
if (factor) | |
*factor = i; | |
return false; | |
} | |
} | |
// Return 0 if none could be found, number is prime | |
return true; | |
} | |
static int primes_in_range(int64_t start, int64_t end) { | |
int64_t n = start < end ? start : end; | |
int64_t e = end > start ? end : start; | |
while (n <= e) { | |
if (is_prime(n, NULL)) { | |
printf("%ld\n", n); | |
} | |
n++; | |
} | |
return EXIT_SUCCESS; | |
} | |
int main(int argc, char **argv) { | |
int64_t c = 0, n = 2; | |
bool process = false; | |
int opt; | |
while ((opt = getopt_long(argc, argv, "c:n:r:t:h", prime_opts, NULL)) != -1) | |
{ | |
switch (opt) | |
{ | |
case 'c': | |
{ | |
c = atoll(optarg); | |
if (c <= 0) | |
{ | |
printf("invalid argument (use -h for help)\n"); | |
return EXIT_FAILURE; | |
} | |
process = true; | |
break; | |
} | |
case 'n': | |
{ | |
n = atoll(optarg); | |
if (n < 0) | |
{ | |
printf("invalid argument (use -h for help)\n"); | |
return EXIT_FAILURE; | |
} | |
break; | |
} | |
case 'r': | |
{ | |
char *token; | |
int64_t start, finish; | |
token = strtok(optarg, ":"); | |
if (token) { | |
start = atoll(token); | |
token = strtok(NULL, ":"); | |
if (token) { | |
finish = atoll(token); | |
if (start < 0 || finish < 0) | |
{ | |
printf("invalid argument (use -h for help)\n"); | |
return EXIT_FAILURE; | |
} | |
return primes_in_range(start, finish); | |
} | |
} | |
printf("invalid argument (use -h for help)\n"); | |
return EXIT_FAILURE; | |
} | |
case 't': | |
{ | |
int64_t f; | |
printf("%ld\n", is_prime(atoll(optarg), &f) ? 0L : f); | |
return EXIT_SUCCESS; | |
} | |
case 'h': | |
printf("-c, [--count] <number> # Sets number of primes to generate\n"); | |
printf("-n, [--number] <number> # Sets the initial value to begin generating from\n"); | |
printf("-r, [--range] <start>:<end> # Sets start and end points to generate all primes between\n"); | |
printf("-t, [--test] <number> # Test if a number if prime. Returns 0 if prime, otherwise the first factor found\n"); | |
printf("-h, [--help] # Displays this help message\n"); | |
printf("\n"); | |
printf("All arguments must be positive numbers, as a all primes are positive by definition.\n"); | |
return EXIT_SUCCESS; | |
default: return EXIT_FAILURE; | |
} | |
} | |
if (!process) { | |
printf("no operation specified (use -h for help)\n"); | |
return EXIT_FAILURE; | |
} | |
int64_t count = 0; | |
do { | |
if (is_prime(n, NULL)) { | |
printf("%ld\n", n); | |
count++; | |
} | |
n++; | |
} while (count < c); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment