advent2021

Advent of Code 2021 Solutions
git clone git://bsandro.tech/advent2021
Log | Files | Refs | README | LICENSE

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 }