#include #include #include #include #include #include "puzzle_input.h" #include "day.h" #define DIAGNOSTIC_LEN 2000 #define MAX_WORD_LEN 50 typedef struct { char word[MAX_WORD_LEN]; uint32_t len; } diagnostic_word_t; typedef enum { OXYGEN = 1, CO2 = 0 } life_support_rating_t; parse_ret_t parse_diagnostic_data(char * buffer, void * data, uint16_t index) { diagnostic_word_t * diagnostic_data = (diagnostic_word_t *)data; diagnostic_data[index].len = strlen(buffer); strncpy(diagnostic_data[index].word, buffer, MAX_WORD_LEN); return PARSER_OK; } static void part_1(diagnostic_word_t * diagnostic_data, uint16_t len) { uint64_t gamma_rate = 0; uint64_t epsilon_rate = 0; uint16_t bit_len = diagnostic_data[0].len; for (int bit_ndx = 0; bit_ndx < bit_len; bit_ndx++) { int32_t one_count = 0; for (int word_ndx = 0; word_ndx < len; word_ndx++) { if (diagnostic_data[word_ndx].word[bit_ndx] == '1') { one_count++; } } if (one_count < len/2) { epsilon_rate |= 1 << (bit_len - bit_ndx - 1); } else { gamma_rate |= 1 << (bit_len - bit_ndx - 1); } } printf("PART 1: The power consumption is %lu * %lu = %lu\n", gamma_rate, epsilon_rate, gamma_rate*epsilon_rate); } int64_t get_rating(diagnostic_word_t * diagnostic_data, uint16_t len, life_support_rating_t mode) { uint16_t bit_len = diagnostic_data[0].len; uint8_t keep[DIAGNOSTIC_LEN]; memset(keep, 1, len); for (int bit_ndx = 0; bit_ndx < bit_len; bit_ndx++) { int32_t one_count = 0; int32_t total = 0; int32_t keep_1 = 0; for (int word_ndx = 0; word_ndx < len; word_ndx++) { if (keep[word_ndx]) { if (diagnostic_data[word_ndx].word[bit_ndx] == '1') { one_count++; } total++; } } if (total == 1) { break; } if ((float)one_count >= ceil(total/2.0)) { keep_1 = mode; } else { keep_1 = !mode; } for (int word_ndx = 0; word_ndx < len; word_ndx++) { if (keep[word_ndx]) { if (diagnostic_data[word_ndx].word[bit_ndx] == '1') { keep[word_ndx] = keep_1; } else { keep[word_ndx] = !keep_1; } } } } for (int word_ndx = 0; word_ndx < len; word_ndx++) { if (keep[word_ndx]) { return strtol(diagnostic_data[word_ndx].word, NULL, 2); } } return -1; } void part_2(diagnostic_word_t * diagnostic_data, uint16_t len) { int64_t oxygen_rating = get_rating(diagnostic_data, len, OXYGEN); int64_t co2_rating = get_rating(diagnostic_data, len, CO2); printf("PART 2: The life support rating is %ld * %ld = %ld", oxygen_rating, co2_rating, oxygen_rating*co2_rating); } static diagnostic_word_t diagnostic_data_g[DIAGNOSTIC_LEN]; int day_3() { uint16_t len; parse_ret_t parse_ret; parse_ret = read_input_single_line("../inputs/day_3.txt", (void *) diagnostic_data_g, DIAGNOSTIC_LEN, parse_diagnostic_data, &len); if (parse_ret != PARSER_OK) { printf("Unable to parse input data: %d", parse_ret); return -1; } part_1(diagnostic_data_g, len); part_2(diagnostic_data_g, len); return 0; }