#include #include #include #include #include "puzzle_input.h" #include "day.h" #define SIGNAL_PATTERN_DIGITS 10 #define OUTPUT_DIGITS 4 #define MAX_ENTRIES 1000 typedef struct { uint8_t signal_patterns[SIGNAL_PATTERN_DIGITS]; uint8_t outputs[OUTPUT_DIGITS]; } display_entry_t; parse_ret_t parse_display(char * display_str, uint8_t * display_state) { while (*display_str != '\0') { uint8_t bit_to_set; if (*display_str < 'a' || *display_str > 'g') { return PARSER_INVALID; } bit_to_set = *display_str - 'a'; *display_state |= 1 << bit_to_set; display_str++; } return PARSER_OK; } parse_ret_t parse_display_group(char * display_group_str, uint8_t * display_group, uint16_t display_group_max_len) { char * tok = strtok(display_group_str, " "); uint16_t display_index = 0; if (display_group_str == NULL) { return PARSE_NULL; } while (tok != NULL) { parse_ret_t ret = parse_display(tok, &display_group[display_index]); if (ret != PARSER_OK) { return ret; } tok = strtok(NULL, " "); display_index++; if (display_index > display_group_max_len) { return PARSER_RANGE_OVERFLOW; } } if (display_index != display_group_max_len) { return PARSER_INVALID; } return PARSER_OK; } parse_ret_t parse_display_entry(char * buffer, void * data, uint16_t index) { display_entry_t * display_entries = (display_entry_t *)data; char * signal_patterns = strtok(buffer, "|"); char * outputs = strtok(NULL, "|"); display_entry_t * entry = &display_entries[index]; parse_ret_t res; res = parse_display_group(signal_patterns, entry->signal_patterns, SIGNAL_PATTERN_DIGITS); if (res != PARSER_OK) { return res; } res = parse_display_group(outputs, entry->outputs, OUTPUT_DIGITS); if (res != PARSER_OK) { return res; } return PARSER_OK; } uint8_t count_bits(uint8_t val) { uint8_t on_count = 0; for (int bit_ndx = 0; bit_ndx < 7; bit_ndx++) { if ((val >> bit_ndx) & 0b1) { on_count++; } } return on_count; } static void part_1(display_entry_t * entries, uint16_t entry_len) { uint32_t easy_digit_count = 0; for (int entry_ndx = 0; entry_ndx < entry_len; entry_ndx++) { display_entry_t * entry = &entries[entry_ndx]; uint32_t count_per_row = 0; for (int disp_ndx = 0; disp_ndx < OUTPUT_DIGITS; disp_ndx++) { uint8_t on_count = count_bits(entry->outputs[disp_ndx]); switch (on_count) { case 2: // 1 case 4: // 4 case 3: // 7 case 7: // 8 count_per_row++; default: break; } } easy_digit_count += count_per_row; } printf("PART 1: Easy digit count is: %u\n", easy_digit_count); } static uint8_t fix_wire_crossing(uint8_t state, uint8_t crossed_four, uint8_t crossed_7) { uint8_t new_state; uint8_t on_count = count_bits(state); switch (on_count) { case 2: // 1 new_state = 1; break; case 3: // 7 new_state = 7; break; case 4: // 4 new_state = 4; break; case 5: // 2, 3, 5 if ((state & crossed_7) == crossed_7) { new_state = 3; } else if (count_bits(state & crossed_four) == 3) { new_state = 5; } else { new_state = 2; } break; case 6: // 0, 6, 9 if ((state & crossed_four) == crossed_four) { new_state = 9; } else if ((state & crossed_7) == crossed_7) { new_state = 0; } else { new_state = 6; } break; case 7: // 8 new_state = 8; break; default: break; } return new_state; } static void part_2(display_entry_t * entries, uint16_t entry_len) { uint32_t sum = 0; for (int entry_ndx = 0; entry_ndx < entry_len; entry_ndx++) { display_entry_t * entry = &entries[entry_ndx]; uint8_t crossed_4 = 0; uint8_t crossed_7 = 0; for (int disp_ndx = 0; disp_ndx < OUTPUT_DIGITS + SIGNAL_PATTERN_DIGITS; disp_ndx++) { uint8_t display_state; if (disp_ndx < SIGNAL_PATTERN_DIGITS) { display_state = entry->signal_patterns[disp_ndx]; } else { display_state = entry->outputs[disp_ndx-OUTPUT_DIGITS]; } uint8_t bit_count = count_bits(display_state); if (bit_count == 4) { crossed_4 = display_state; } else if (bit_count == 3) { crossed_7 = display_state; } } if (crossed_7 == 0 || crossed_4 == 0) { printf("oopsie woopise, a lil fucky wucky\n"); return; } for (int disp_ndx = 0; disp_ndx < OUTPUT_DIGITS; disp_ndx++) { uint8_t display_state = entry->outputs[disp_ndx]; uint8_t val = fix_wire_crossing(display_state, crossed_4, crossed_7); sum += (val * (int32_t)pow(10, (OUTPUT_DIGITS-disp_ndx-1))); } } printf("PART 2: Output sum: %d\n", sum); } display_entry_t entries_g[MAX_ENTRIES] = {0}; int day_8() { parse_ret_t res; uint16_t display_len; res = read_input_single_line("../inputs/day_8.txt", (void *)entries_g, MAX_ENTRIES, parse_display_entry, &display_len); if (res != PARSER_OK) { printf("Unable to parse input: %d\n", res); return -1; } part_1(entries_g, display_len); part_2(entries_g, display_len); return 0; }