#include // Pour les printf #include // pour atoi #include // pour strcmp enum month { JANUARY=1, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBRE, OCTOBER, NOVEMBER, DECEMBER }; int is_leap(int year) // Also called leap year { return (year%4 == 0 && year%100 != 0) || year%400 == 0; } int days_count(enum month m, int year) { switch (m) { case JANUARY: case MARCH: case MAY: case JULY: case AUGUST: case OCTOBER: case DECEMBER: return 31; case FEBRUARY: return is_leap(year) ? 29 : 28; case APRIL: // Pourquoi faire ces cas la, quand on pourrait tout mettre dans le default ? case JUNE: case SEPTEMBRE: case NOVEMBER: return 30; default: return -1; } } /* Personellement, j'aime moins cette solution. En effet les conditions sont moins claires * et deviendraient compliqué s'il y avait plus d'un cas particulier */ int days_count2(enum month month, int year) { int day_by_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (month < JANUARY || month > DECEMBER) return -1; days = day_by_month[month - 1]; if (days < 30) days = is_leap(year) ? 29 : 28; return days; } int exo1(int argc, char* argv[]) { int month = (argc > 1) ? atoi(argv[1]) : 4; int year = (argc > 2) ? atoi(argv[2]) : 2013; printf("l'annee %d %s bissextile", year, is_leap(year) ? "est" : "n'est pas"); printf("le mois '%d' a '%d' jours\n", month, days_count(month, year)); // exo 1 return 0; } void print_ascii_table_1() { printf("Char.\tdec.\thex\toct\n"); for (int i = 'A'; i <= 'Z'; i = i + 1) printf("%c\t%d\t%x\t%o\n", i, i, i, i); //for(char i = 0; i <= 0xFF ; i = i + 1) // Avec des char au lieu des ints // printf("'%hhc'\t%hhd\t%hhx\t%hho", i, i, i, i); } void print_ascii_table_2(int n) { if (!n) n = 1; // Pour eviter la division par zero for (int i = 0; i < n; i = i + 1) printf("Char.\tdec.\thex\toct\t"); // note, on aura un tab de trop // ... mais c'est pas trop grave, printf("\n"); for (int i = 0x20; i < 0x80; i = i + 1) { // Seulement la plage affichable printf("%c\t%d\t%x\t%o", i, i, i, i); printf((i % n == n - 1 || i == 0x80) ? "\n" : "\t"); } } void print_ascii_table_3(int n, int min, int max) { if (n < 1) n = 1; if (n > (max - min)) // on s'assure qu'il n'y ai pas plus de colonnes que d'entrées à afficher n = max - min; for (int i = 0; i < n ; i = i + 1) printf("Char.\tdec.\thex\toct%s", (i % n == n - 1) ? "\n" : "\t"); for (int i = min; i <= max; i = i + 1) { int c = (i < 0x20 || i > 0x80) ? ' ' : i; printf("%c\t%d\t%x\t%o", c, i, i, i); printf((i % n == n - 1 || i == max) ? "\n" : "\t"); } } int exo2(int argc, char* argv[]) { int nb = 4; int min = 32; int max = 255; if (argc > 1) // Dans le cas du bonus, pour assurer qu'on lit bien tout le monde nb = atoi(argv[argc - 1]); for (int i = 1; i < argc - 1; i = i + 1) // Pour le bonus if (strcmp(argv[i], "--min") == 0) { i = i + 1; min = atoi(argv[i]); } else if (strcmp(argv[i], "--max") == 0) { i = i + 1; max = atoi(argv[i]); } else nb = atoi(argv[i]); printf("%d %d %d \n", nb, min, max); print_ascii_table_1(); printf("\n"); print_ascii_table_2(nb); printf("\n"); print_ascii_table_3(nb, min, max); printf("\n"); return EXIT_SUCCESS; } // Avec un sizeof // Complexite pire des cas: sizeof(int) int bit_count_1(unsigned long long nb) { int count = 0; for (int j = 0; j < sizeof(nb)*8; j = j + 1) { if (nb & (1LL << j)) count = count + 1; } return count; } // Plus efficace en moyenne (pareil dans le pire des cas) // Complexite : dernier bit a gauche (most significant bit) int bit_count_2(unsigned long long nb) { // On est oblige de le considerer comme non-signe a cause du décalage a droite int count = 0; while (nb) { if (nb & 1) count = count + 1; nb = nb >> 1; } return count; } /* Ceci est une variation de bit_count_2, qui n'utilise pas de unsigned*/ int bit_count_2_2(long long nb) { int count = 0; if (nb < 0) { nb ^= 1 << (sizeof(nb)*8 - 1); // on enleve le bit de poit fort count = count + 1; } while (nb) { if (nb & 1) count = count + 1; nb = nb >> 1; } return count; } // La version du hackers delight // Plus efficace en moyenne (pareil dans le pire des cas) // Complexite : nombre de bit a 1 int bit_count_3(long long nb) { int count = 0; while (nb) { count = count + 1; nb = nb ^ (nb & -nb); } return count; } // La version qui marche que avec des entiers de 32bits et qui poutre, ditte 'parallel count' // sur une machine moderne (i.e. temps constant et sans condition [sans branchement]) int bit_count_4(unsigned i) // Unsigned à cause des décallage à droite { i = i - ((i >> 1) & 0x55555555); i = (i & 0x33333333) + ((i >> 2) & 0x33333333); return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24; } int exo3(int argc, char *argv[]) { for (int i = 1; i < argc; i = i + 1) { long long nb = atoll(argv[i]); printf("%lld (%llx) contient %d %d %d bits a 1\n", nb, nb, bit_count_1(nb), bit_count_2(nb), bit_count_3(nb)); } return EXIT_SUCCESS; }