Cod sursa(job #2326805)

Utilizator AxellApostolescu Alexandru Axell Data 24 ianuarie 2019 01:04:43
Problema Ciurul lui Eratosthenes Scor 30
Compilator c-64 Status done
Runda Arhiva educationala Marime 1.59 kb
#include <stdio.h>
#include <stdlib.h>

// Vom folosi conventia: x = 0 inseamna ca x e in set si x = 1 in caz contrar
// Returneaza 1 daca valoarea e in set, 0 in caz contrar
int is_in_set(unsigned char *s, int value) {
	int bit = value % 8;
	int byte = value / 8;
	unsigned char mask = 1;
	mask <<= bit;
	if (s[byte] & mask) {
		return 0; // Nu e in set
	}
	return 1; // Este in set
}
void remove_from_set(unsigned char *s, int value) {
	int bit = value % 8;
	int byte = value / 8;
	unsigned char mask = 1;
	mask <<= bit;
	s[byte] |= mask;
}

int is_prime(int value) {
	for (int i = 2 ; i * i <= value ; ++i) {
		if (value % i == 0) {
			return 0; // Nu e prim
		}
	}
	return 1; // E prim
}

void multiple_removal(unsigned char *s, int val, int n) {
	for (int i = val * val ; i <= n ; i+= val) {
		remove_from_set(s, i);
	}
}

void ciur(int n, unsigned char *s) {
	int i;
	for(i = 2 ; i <= n ; ++i) {
		if (is_prime(i)) {
			multiple_removal(s, i, n);
		}
	}
}

void print_set(int n, unsigned char *s, FILE* out) {
	int i, count = 0;
	for (i = 2 ; i <= n ; ++i) {
		if (is_in_set(s, i)) {
			count++;
		}
	}
	fprintf(out, "%d\n", count);
}

int main() {
	int n;
	FILE* in = fopen("ciur.in", "rt");
	if (in == NULL) {
		printf("Couldn`t open the input file!\n");
		return -1;
	}
	FILE* out = fopen("ciur.out", "wt");
	if (out == NULL) {
		printf("Couldn`t open the output file!\n");
		return -2;
	}
	fscanf(in, "%d", &n);
	unsigned char *s = calloc(((n + 7) / 8 + 1), sizeof(char));
	// Executie
	ciur(n, s);
	print_set(n, s, out);
	// Inchidem fisierele si eliberam memoria
	free(s);
	fclose(in);
	fclose(out);
	return 0;
}