Day 3 Done

+ Now linking in the math library, will probably be needed for future challenges anyway
+ This day was a bit of a hack
main
Joey Hines 2021-12-03 18:53:15 -07:00
parent d853ba0b10
commit bec55c46dd
No known key found for this signature in database
GPG Key ID: 80F567B5C968F91B
8 changed files with 1158 additions and 9 deletions

View File

@ -3,4 +3,5 @@ project(aoc_2021 C)
set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD 99)
add_executable(aoc_2021 src/main.c src/day_1.c src/day.h src/day_2.c src/puzzle_input.c src/puzzle_input.h) add_executable(aoc_2021 src/main.c src/day_1.c src/day.h src/day_2.c src/puzzle_input.c src/puzzle_input.h src/day_3.c)
target_link_libraries(aoc_2021 m)

1000
inputs/day_3.txt 100644

File diff suppressed because it is too large Load Diff

View File

@ -3,5 +3,6 @@
int day_1(); int day_1();
int day_2(); int day_2();
int day_3();
#endif //AOC_2021_DAY_H #endif //AOC_2021_DAY_H

View File

@ -1,7 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h> #include <string.h>
#include "puzzle_input.h" #include "puzzle_input.h"
@ -27,7 +25,7 @@ int parse_course_entry(char * buffer, void * data, uint16_t data_index) {
parse_ret_t ret; parse_ret_t ret;
int64_t units; int64_t units;
ret = parse_long(unit_str, &units); ret = parse_long(unit_str, &units, 10);
if (ret == PARSER_OK) { if (ret == PARSER_OK) {
course_dir_t dir; course_dir_t dir;
@ -115,6 +113,8 @@ int day_2() {
else { else {
printf("Failed to parse data: %d", res); printf("Failed to parse data: %d", res);
} }
return 0;
} }

135
src/day_3.c 100644
View File

@ -0,0 +1,135 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#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;
}
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("../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;
}

View File

@ -22,6 +22,9 @@ int main(int argc, char * argv[]) {
case 2: case 2:
day_2(); day_2();
break; break;
case 3:
day_3();
break;
default: default:
printf("Invalid day ding dong!\n"); printf("Invalid day ding dong!\n");
return -2; return -2;

View File

@ -4,8 +4,8 @@
#include <stdio.h> #include <stdio.h>
#include "puzzle_input.h" #include "puzzle_input.h"
parse_ret_t parse_long(char * buffer, int64_t *val) { parse_ret_t parse_long(char * buffer, int64_t *val, int16_t base) {
*val = strtol(buffer, NULL, 10); *val = strtol(buffer, NULL, base);
if (*val == LONG_MIN || *val == LONG_MAX) { if (*val == LONG_MIN || *val == LONG_MAX) {
return PARSER_INVALID; return PARSER_INVALID;
@ -15,12 +15,12 @@ parse_ret_t parse_long(char * buffer, int64_t *val) {
} }
parse_ret_t parse_long_from_buff(char * buffer, void * data, uint16_t index) { static parse_ret_t parse_long_base_from_buff(char * buffer, void * data, uint16_t index, uint16_t base) {
uint64_t * int_data = (uint64_t *)data; uint64_t * int_data = (uint64_t *)data;
uint64_t val; uint64_t val;
int ret; int ret;
ret = parse_long(buffer, (int64_t *)&val); ret = parse_long(buffer, (int64_t *)&val, base);
if (ret != PARSER_OK) { if (ret != PARSER_OK) {
return ret; return ret;
@ -31,6 +31,14 @@ parse_ret_t parse_long_from_buff(char * buffer, void * data, uint16_t index) {
return PARSER_OK; return PARSER_OK;
} }
parse_ret_t parse_long_from_buff(char * buffer, void * data, uint16_t index) {
return parse_long_base_from_buff(buffer, data, index, 10);
}
parse_ret_t parse_long_base_2_from_buff(char * buffer, void * data, uint16_t index) {
return parse_long_base_from_buff(buffer, data, index, 2);
}
parse_ret_t read_input(const char * file_path, void * data, uint16_t max_len, input_parser_t parser, uint16_t * len) { parse_ret_t read_input(const char * file_path, void * data, uint16_t max_len, input_parser_t parser, uint16_t * len) {
char buffer[64]; char buffer[64];
int c; int c;

View File

@ -16,8 +16,9 @@ parse_ret_t read_input(const char * file_path, void * data, uint16_t max_len, in
// Parsers // Parsers
parse_ret_t parse_long_from_buff(char * buffer, void * data, uint16_t index); parse_ret_t parse_long_from_buff(char * buffer, void * data, uint16_t index);
parse_ret_t parse_long_base_2_from_buff(char * buffer, void * data, uint16_t index);
//Helpers //Helpers
parse_ret_t parse_long(char * buffer, int64_t * val); parse_ret_t parse_long(char * buffer, int64_t * val, int16_t base);
#endif //AOC_2021_PUZZLE_INPUT_H #endif //AOC_2021_PUZZLE_INPUT_H