summaryrefslogblamecommitdiff
path: root/set_bitsets.c
blob: 2c85277d48c967dc8fc9180196acaa3b128c97ea (plain) (tree)
1
2
3
4
5
6
7
8
9








                                                                      
                 

                   

                                                               
 
                                                                





                                






                                                                 
                          
                     
 
 

                      
                
              





                                       

                           

 
                          

                                 
                                 
                                
                                      




                       
                     


                                      
                       
                                                                             
                                   
         
                                 

                                 
                                             

                                              


                                      
                       
                                                                                    
                                   
         
                                 

                                 
                                             

                                              



                                     
                       
                                                                                  
                                   
         
                                 
                                  
                                                  

                                              

 
                               
                                

 
                                        


                                              




                                               
                              
         
              




                                       
                              

                                 
                                                       

                                                
                    
                      

 


                                        

                                                        









                                                            
                              




                                                                                     

 
                                 




                                                                                  

 


                           
                          

                              
                                  
 
 

                         


                         


                    
 
/*
	Projet d'algorithmique et programmation 2013-2014
	(cours de C.Matthieu et J.Stern)
	Alex AUVOLAT, Mendes OULAMARA

	Implémentation des ensembles d'entiers sous forme de bitsets.
	Code sous la juridiction de Mendes OULAMARA.
*/

#include "sets.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#define SCOD (unsigned long long)(8*sizeof(unsigned long long))

int nbCells(int n){		//the mathematical ceil function
	if(n == (n/SCOD)*SCOD)
		return n/SCOD;
	else
		return n/SCOD+1;
}

int nb_one(unsigned long long x) {	//the hamming weight of x
    int cnt = 0, i;
    for(i = 0; i < SCOD; i++)
	cnt+= ((x>>i)&1);
    return cnt;
}

int set_size(const set s){
    return *(s.size);
}

set empty_set(int n){
    	assert(n > 0);
	set res;
	int i;
	res.N = n;
	res.size = malloc(sizeof(int));
	*(res.size) = 0;
	int NC = nbCells(n);
	res.tab = malloc(SCOD*NC/8);
	for(i = 0; i < NC; i++)
	    res.tab[i] = 0;
	return res;
}

set copy_set(const set s){
	set res = empty_set(s.N);
	*(res.size) = *(s.size);
	int NC = nbCells(s.N), i;
	for(i = 0; i < NC; i++) 
		res.tab[i] = s.tab[i];
	return res;
}

void delete_set(set a){
	free(a.tab);
	free(a.size);
}

void set_union_ip(set a, const set b){
	if(a.N != b.N){
		printf("Union failed : the sets don't have the same size\n");
		assert(a.N == b.N);
	}
	int NC = nbCells(a.N), i;
	*(a.size)=0;
	for(i = 0; i < NC; i++) {
		a.tab[i] = a.tab[i]|b.tab[i];
		*(a.size) += nb_one(a.tab[i]);
	}
}

void set_inter_ip(set a, const set b){
	if(a.N != b.N){
		printf("Intersection failed : the sets don't have the same size\n");
		assert(a.N == b.N);
	}
	int NC = nbCells(a.N), i;
	*(a.size)=0;
	for(i = 0; i < NC; i++){ 
		a.tab[i] = a.tab[i]&b.tab[i];
		*(a.size) += nb_one(a.tab[i]);
	}
}


void set_diff_ip(set a, const set b){
	if(a.N != b.N){
		printf("Difference failed : the sets don't have the same size\n");
		assert(a.N == b.N);
	}
	int NC = nbCells(a.N), i;
	for(i = 0; i < NC; i++) { 
		a.tab[i] = a.tab[i] & (~b.tab[i]);
		*(a.size) += nb_one(a.tab[i]);
	}
}

bool is_set_empty(const set s){
    	return (*(s.size) == 0);
}

inline bool set_mem(int x, const set s){
    	unsigned long long ux = x;
    	assert(x < s.N && x >= 0);
	return  (s.tab[ux/SCOD]>>(ux%SCOD))&1;
}

int dyadic_val(unsigned long long x){
	if(x == 0){
		printf("Infinite valuation\n");
		assert(false);
	}
	int i;
	for(i=0; ((x>>i)&1) == 0; i++);
	return i;
}

int elt_of_set(const set s){
	int N=nbCells(s.N), i;
	for(i=0; i<N; i++)
		if(s.tab[i] != 0)
		    return i*SCOD+dyadic_val(s.tab[i]);

	printf("No element in an empty set!\n");
	dump_set(s);
	assert(false);
}

int elt_of_set_heur(const set s, int h){
    int N=nbCells(s.N), i;

    if(s.tab[h/SCOD]>>(h%SCOD) !=0)
	return h + dyadic_val(s.tab[h/SCOD]>>(h%SCOD)) ;

    for(i=0; i<N; i++)
	if(s.tab[(i+h/SCOD+1)%N] != 0)
	    return i*SCOD+dyadic_val(s.tab[(i+h/SCOD+1)%N]);

	printf("No element in an empty set!\n");
	dump_set(s);
	assert(false);
}

void set_add_ip(int x, set s){
    	unsigned long long ux = x;
    	if(! set_mem(ux, s)){
		s.tab[ux/SCOD] = s.tab[ux/SCOD] | (unsigned long long)(1)<<(ux%SCOD);
		*(s.size) = *(s.size)+1;
	}
}

void set_remove_ip(int x, set s){
    	unsigned long long ux = x;
    if(set_mem(ux, s) ) {
	s.tab[ux/SCOD] = s.tab[ux/SCOD] & (~((unsigned long long)(1)<<(ux%SCOD)));
	*(s.size) = *(s.size)-1;
    }
}

void dump_set(const set s){
    int i=0;
    printf("[");
    for(i=0; i < s.N; i++)
	if(set_mem(i, s))
	    printf(" %d ", i);
    printf("] (%d)\n", *(s.size));
}

set full_set(int n) {
    set r = empty_set(n);
    *(r.size) = n;
    int NC=nbCells(n), i;
    for(i=0; i< NC; i++)
	r.tab[i]=-1;
    return r;
}