Cod sursa(job #2335411)

Utilizator AxellApostolescu Alexandru Axell Data 4 februarie 2019 01:06:54
Problema Ciurul lui Eratosthenes Scor 30
Compilator c-64 Status done
Runda Arhiva educationala Marime 1.28 kb
#include <stdio.h>
#include <stdlib.h>
#define MAX 250000

void exclude_from_set(unsigned char *s, int val) {
	int bit = val % 8, byte = val / 8;
	unsigned char mask = 1 << bit;
	s[byte] |= mask;
}

int is_prime(int val) {
	for (int i = 2 ; i * i <= val ; ++i) {
		if (val % i == 0) {
			return 0;
		}
	}
	return 1;
}

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

int count_bits(unsigned char val) {
	int ct = 0;
	while (val) {
		val &= (val - 1);
		ct++;
	}
	return ct;
} 

int cardinal(unsigned char *s, int n) {
	int i, last_byte = (n + 7) / 8;
	for (i = 0 ; i <= last_byte ; ++i) {
		n -= count_bits(s[i]);
	}
	return n + 1;
}

int main() {
	FILE *in, *out;
	if (((in = fopen("ciur.in", "rt")) == NULL)) {
		printf("Nu am putut deschide fisierul de input!");
		return -1;
	}
	if (((out = fopen("ciur.out", "wt")) == NULL)) {
		printf("Nu am putut deschide fisierul de output!");
		return -2;
	}
	unsigned char *s = calloc(MAX, sizeof(char));
	if (s == NULL) {
		printf("Ai belit pula\n");
		return -3;
	}
	int n;
	s[0] |= 3;
	fscanf(in, "%d", &n);
	execute(s, n);
	fprintf(out, "%d\n", cardinal(s, n));
	// Freeing the memory
	free(s);
	fclose(in);
	fclose(out);
	return 0;
}