puzzle1.c (1546B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <errno.h> 4 #include <string.h> 5 #include <strings.h> 6 #include <stdbool.h> 7 8 #define FMT_(l) #l 9 #define FMT(l) FMT_(l) 10 11 #define MAX_LEN 16 12 #define BITS_COUNT 12 13 #define STR_LEN 13 // BITS_COUNT + 1 14 #define FMT_STRING "%" FMT(STR_LEN) "s" 15 16 // No idea about the case when number (1/0) counts are equal, 17 // it is not described in the task. 18 19 int puzzle1(const char *filename) { 20 FILE *infile = fopen(filename, "r"); 21 if (infile == NULL) { 22 fprintf(stderr, "fopen() error: %s\n", strerror(errno)); 23 return -1; 24 } 25 26 char buf[MAX_LEN] = {0}; 27 char str[STR_LEN] = {0}; 28 int ones_count[BITS_COUNT] = {0}; 29 int glob_count = 0; 30 31 // reading file data, counting ones and zeroes 32 while (fgets(buf, MAX_LEN, infile) != NULL) { 33 if (sscanf(buf, FMT_STRING, str) == 1) { 34 for (int i = 0; i < BITS_COUNT; ++i) { 35 if (str[i] == '1') { 36 ++ones_count[i]; 37 } 38 } 39 ++glob_count; 40 bzero(buf, MAX_LEN); 41 bzero(str, STR_LEN); 42 } 43 } 44 45 const int count_threshold = glob_count / 2; 46 int gamma = 0, epsilon = 0; 47 bool bit_val = 0; 48 49 // ones_count array: [bit#11, bit#10, bit#9, ... #bit0] 50 for (int i = 0; i < BITS_COUNT; ++i) { 51 // we count bits from 0, so need to subtract 1 to not set actual 52 // bit 12 that is above designated [bits 0..11] range 53 const int bit_num = BITS_COUNT - i - 1; 54 bit_val = ones_count[i] > count_threshold; 55 56 if (bit_val) { 57 gamma |= 1 << bit_num; 58 } else { 59 epsilon |= 1 << bit_num; 60 } 61 } 62 63 // mutiny! ignoring feof/ferror. 64 65 fclose(infile); 66 return gamma * epsilon; 67 }