feat: add listprimes

This commit is contained in:
dancingCycle 2023-01-19 13:18:35 +01:00
parent 68d3c97905
commit f0e0903cd9
7 changed files with 236 additions and 0 deletions

View File

@ -0,0 +1,18 @@
/* Contains code to create and manipulate a linked list of `int`s */
typedef struct elem {
int val;
struct elem* next;
} elem;
elem* create(int val, elem* prev_elem);
// Add a new elem number to the linked list
void display(elem* first_elem);
// Print out the current list of elems
void release(elem* first_elem);
// Release the memory used by the linked list
int check_membership(int val, elem* first_elem);
// Check linked list for presence of `val`

View File

@ -0,0 +1,13 @@
/* Contains code to create a linked list of prime numbers. */
elem* first_n_primes(int n);
// Return a pointer to the first element in a linked list of the first n
// primes
elem* primes_lte_n(int n);
// Return a pointer to the first element in a linked list of all primes
// less than or equal to `n`
int is_prime(int x, elem* first_prime);
// Check if x is prime, given a linked list of prime numbers (assumed
// valid)

50
listprimes/linkedlist.c Normal file
View File

@ -0,0 +1,50 @@
/* Contains code to create and manipulate a linked list of `int`s */
#include <stdio.h>
#include <stdlib.h>
#include "linkedlist.h"
elem* create(int val, elem* prev_elem) {
// Add a new elem number to the linked list
elem* new_elem = malloc(sizeof(elem));
new_elem->val = val;
new_elem->next = NULL;
if (prev_elem != NULL) prev_elem->next = new_elem;
return new_elem;
}
void display(elem* first_elem) {
// Print out the current list of elems
elem* cur_elem = first_elem;
int i = 1;
while (cur_elem != NULL) {
printf("(%i) %i\n", i, cur_elem->val);
cur_elem = cur_elem->next;
i++;
}
}
void release(elem* first_elem) {
// Release the memory used by the linked list
elem *cur_elem = first_elem, *next_elem;
while (cur_elem != NULL) {
next_elem = cur_elem->next; // Store pointer to next elem
free(cur_elem); // release memory for the current elem
cur_elem = next_elem; // next iteration, free the next elem
}
}
int check_membership(int val, elem* first_elem) {
// Check linked list for presence of `val`
int found_val = 0;
elem* cur_elem = first_elem;
while (cur_elem != NULL) {
if (val == cur_elem->val) {
found_val = 1;
break;
} else {
cur_elem = cur_elem->next;
}
}
return found_val;
}

57
listprimes/listprimes.c Normal file
View File

@ -0,0 +1,57 @@
/* Contains code to create a linked list of prime numbers. */
#include <stdlib.h>
#include <math.h>
#include "linkedlist.h"
#include "listprimes.h"
elem* first_n_primes(int n) {
// Return a pointer to the first element in a linked list of the first n
// primes
elem *first_prime = create(2, NULL), *cur_prime = first_prime;
int cur_val = 3, list_len = 1;
// Iterate until list of primes is desired length
while (list_len < n) {
if (is_prime(cur_val, first_prime)) { // cur_val is prime
cur_prime = create(cur_val, cur_prime); // add to linked list
list_len ++;
// printf("(%i) %i\n", list_len, cur_val);
}
cur_val += 2;
}
return first_prime;
}
elem* primes_lte_n(int n) {
// Return a pointer to the first element in a linked list of all primes
// less than or equal to `n`
elem *first_prime = create(2, NULL), *cur_prime = first_prime;
int cur_val = 3, list_len = 1;
// Iterate until all primes less than n have been considered
while (cur_val <= n) {
if (is_prime(cur_val, first_prime)) { // cur_val is prime
cur_prime = create(cur_val, cur_prime); // add to linked list
list_len ++;
// printf("(%i) %i\n", list_len, cur_val);
}
cur_val += 2;
}
return first_prime;
}
int is_prime(int x, elem* first_prime) {
// Check if x is prime, given a linked list of prime numbers (assumed
// valid)
elem* cur_prime = first_prime;
double sqrtx = sqrt((double)x);
// Iterate through each element of the linked list
while (cur_prime != NULL) {
if (x % cur_prime->val == 0) return 0;
else if (cur_prime->val > sqrtx) return 1;
else cur_prime = cur_prime->next;
}
return 1;
}

56
listprimes/main.c Normal file
View File

@ -0,0 +1,56 @@
/* Compile and run using:
gcc listprimes.c linkedlist.c main.c -o list-primes && list-primes 0 100
*/
#include <stdio.h>
#include <stdlib.h>
#include "linkedlist.h"
#include "listprimes.h"
typedef enum {FIRST_N_PRIMES, PRIMES_LTE_N} mode_type;
const int DEFAULT_MODE = FIRST_N_PRIMES; // by default, list first n primes
const int DEFAULT_N = 20; // by default, list first 20 primes
int main(int argc, char** argv) {
// Read arguments / use defaults
mode_type mode;
int n;
switch (argc) {
case 1: // no args provided, use defaults
mode = DEFAULT_MODE;
n = DEFAULT_N;
break;
case 2: // 1 arg, use default mode and custom n
mode = DEFAULT_MODE;
n = atoi(argv[1]);
break;
case 3: // custom args, check validity
mode = (mode_type) atoi(argv[1]);
n = atoi(argv[2]);
break;
default: // error
fprintf(stderr, "Error: Please enter valid arguments\n");
return 1;
}
// Create appropriate list of primes
elem* prime_list;
switch (mode) {
case FIRST_N_PRIMES:
prime_list = first_n_primes(n);
break;
case PRIMES_LTE_N:
prime_list = primes_lte_n(n);
break;
default:
fprintf(stderr, "Error: Invalid mode type\n");
return 2;
}
// Display list of primes and release memory
display(prime_list);
release(prime_list);
return 0;
}

20
listprimes/makefile Normal file
View File

@ -0,0 +1,20 @@
#target: dependency_1 dependency_2 dependency_3 ...
# command
#
RM = /bin/rm -f
OBJ = main.o listprimes.o linkedlist.o
#
list-primes: $(OBJ)
gcc $(OBJ) -o list-primes -lm
#
linkedlist.o: linkedlist.c includes/linkedlist.h
gcc -I ./includes -c linkedlist.c -o linkedlist.o
#
listprimes.o: listprimes.c includes/linkedlist.h includes/listprimes.h
gcc -I ./includes -c listprimes.c -o listprimes.o
#
main.o: main.c includes/linkedlist.h includes/listprimes.h
gcc -I ./includes -c main.c -o main.o
#
clean:
$(RM) $(OBJ) list-primes *~

22
listprimes/readme.md Normal file
View File

@ -0,0 +1,22 @@
[source](https://gist.github.com/jakelevi1996/ce46a808fe3b5ef06ece63aea0bd2fed)
* build
```
/usr/bin/gcc main.c listprimes.c linkedlist.c -o list-primes -lm
```
* build in two steps (object files, executable file)
```
gcc -c main.c -I ./includes
gcc -c listprimes.c -I ./includes
gcc -c linkedlist.c -I ./includes
gcc main.o listprimes.o linkedlist.o -o list-primes -lm
```
* run
```
./list-primes
```