Skip to content

Instantly share code, notes, and snippets.

@ForeverZer0
Created February 25, 2020 16:48
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 ForeverZer0/bb731cbac821ecd0a8bbfe72dfb9c3f6 to your computer and use it in GitHub Desktop.
Save ForeverZer0/bb731cbac821ecd0a8bbfe72dfb9c3f6 to your computer and use it in GitHub Desktop.
Prime number generator
#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