Skip to content
Extraits de code Groupes Projets

Master

Ouvert Giovanna Stefanelli a demandé de fusionner stefanelli/projet3_first_pull_request:master vers master
1 fichier
+ 218
0
Comparer les modifications
  • Côte à côte
  • En ligne
main.c 0 → 100644
+ 218
0
// #include not used in this version
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
// #include used in this version
#include <errno.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include <time.h>
/*
* STRUCTURE
* "struct factorization"
* "prime_dividers" is an array containing max 10 dividers
* "cnt" is the number of calculated dividers
* "number" is the number to calculate its prime dividers
*/
#define N 10 // Max number of dividers
typedef struct factorization {
unsigned long prime_dividers[N];
unsigned int cnt;
unsigned long number;
} factor;
/* struct file_descriptors
* "in" is the inputfile file descriptor
* "out" is the outputfile file descriptor
* "options" "v" (verbose) with debugging information, "q" without debugging information
*/
typedef struct file_descriptors {
FILE *in;
FILE *out;
char options;
} fd;
/*
* FUNCTIONS used in the programme:
* bool is_div(unsigned long, unsigned long);
* bool is_prime(unsigned long);
* factor *prime_divs(unsigned long);
* void *read_write(fd);
*/
bool is_div(unsigned long numbr, unsigned long i){
if((numbr % i) == 0) { // verify if i is the divider of numbr
return(true); // i is a divider of numbr
} else {
return(false); // i is not a divider of numbr
}
}
bool is_prime(unsigned long nbr) {
/*
* Optimised solution with less loop, see: https://fr.wikipedia.org/wiki/Nombre_premier
* "Crible d'Ératosthène:
* Les premiers algorithmes pour décider si un nombre est premier
* (appelés tests de primalité) consistent à essayer de le diviser par tous les nombres
* qui n'excèdent pas sa racine carrée"
*/
// for(unsigned long j = 2; j <= nbr; j++) { // OLD SOLUTION LESS EFFICIENT
for (unsigned long j = 2; j <= sqrt(nbr); j++) {
if ((nbr % j) == 0) { // verify if i is the divider of nbr
return (false); // i is a divider of nbr
}
}
return (true); // i is a prime number
}
/*
Piste d'amélioration : si le nombre n'est pas divisible par 2, on ne considère que les nombres impairs.
bool is_prime(unsigned long nbr){
if (nbr%2==0){
for(unsigned long j = 2; j <= sqrt(nbr); j++) {
if(is_div(nbr, j) == true)
return(false);
}
return(true);
}
else{
for(unsigned long j = 3; j <= sqrt(nbr); j+=2) {
if(is_div(nbr, j) == true)
return(false);
}
return(true);
}
*/
factor* prime_divs (unsigned long numbr) {
factor *dividers; // Structure storing dividers and their number
// Allocation of memory for "struct factor" and initialize to zero
dividers = (factor *) calloc(1, sizeof(factor));
//memset(dividers, 0, sizeof(factor)); //To be used with malloc
unsigned int n = 0;
dividers->number = numbr;
unsigned long tmp_number = dividers->number;
//for(unsigned long i = 2; i < number; i++) { //Old python approach
//for(unsigned long i = 2; i <number; i++) {
for(unsigned long i = 2; i <= tmp_number ; i++) {
/*
* !!!!! MAJOR CODE CHANGE !!!!!
* Speed increased by 200 time:
* from an average of 22 sec. to 0.11 sec.
* Old code reminder:
* if((is_prime(i) == true) && (is_div(dividers->number,i) == true)){
* */
if(is_div(dividers->number,i) == true){
if(is_prime(i) == true){
dividers->prime_dividers[n] = i;
// The max numbers of loops is reduced
// from "number" to "tmp_number/i"
tmp_number = tmp_number/i;
if(i != dividers->number) {
n++;
}
}
}
}
dividers->cnt = n;
return(dividers);
}
void *read_write(fd *f) {
factor *dividers;
unsigned long number;
// Read input file line by line till the end of file (eof)
while(!feof(f->in)) {
fscanf(f->in, "%lu\n", &number); // Read number to be factored
///
/* Verify if the number is prime or not, in this case the dividers are calculated */
dividers = prime_divs(number); // Core function of the app //
///
if(f->options == 'v') {
printf("\nNumber: %lu ", dividers->number);
}
fprintf(f->out, "Number: %lu ", dividers->number);
if(dividers->cnt != 0) {
for(int i = 0; i < dividers->cnt; i++) {
if(f->options == 'v') {
printf("%lu ", dividers->prime_dividers[i]);
}
fprintf(f->out, " %lu", dividers->prime_dividers[i]);
/* Write a file possible solutions
* "fwrite(&tmp, sizeof(tmp), 1, fd_out);"
* "fwrite(x, sizeof(x[0]), sizeof(x)/sizeof(x[0]), fp);" */
}
} else {
fprintf(f->out, "This is a prime number");
if(f->options == 'v') {
printf("This is a prime number");
}
}
fprintf(f->out, "\n");
free(dividers);
}
return(0);
}
/********* MAIN PROGRAMME **********/
int main (int argc, char *argv[]) {
// Declare f (type fd). Structure containing the file descriptors
fd *f;
// Input arguments
char *inputfile; // Input filemane (string)
char *outputfile; // Output filemane (string)
/*
* START CLOCK to measure CPU time
* calculate programme performance
*/
clock_t start, end;
double cpu_time_used;
start = clock();
/* Allocation of memory for "struct file_descriptors" */
f = (fd *) calloc(1, sizeof(fd));
if (argc == 4) { // Check if the number of arguments is correct
inputfile = argv[1];
outputfile = argv[2];
char *opt = argv[3]; // v or q
f->options = *opt;
} else {
printf("%s\n", "Many or few arguments");
exit(EXIT_FAILURE);
}
if (f->options == 'v') {
system("pwd"); // Info on current working directory
printf("\n -- Programme start --\n");
printf(" nr arguments: %d\n", argc);
printf(" input file: %s\n", inputfile);
printf(" output file: %s\n", outputfile);
printf(" option: %c\n", f->options);
}
/* Open input and output files */
f->in = fopen(inputfile, "r");
f->out = fopen(outputfile, "a+");
if ((f->in == NULL) || (f->out == NULL)) {
exit(EXIT_FAILURE);
}
read_write(f); // Start the programme kernel
/* END CLOCK to measure CPU time */
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
fprintf(f->out, "\nThe programme execution needed %.2f seconds\n\n", cpu_time_used);
if (f->options == 'v') {
printf("\n\nThe programme execution needed %.2f seconds", cpu_time_used);
printf("\n -- Programme end --\n");
}
fclose(f->in);
fclose(f->out);
free(f); // Free the memory allocated with malloc
return (EXIT_SUCCESS);
}
Chargement en cours