Day 3 Done
+ Now linking in the math library, will probably be needed for future challenges anyway + This day was a bit of a hackmain
parent
d853ba0b10
commit
bec55c46dd
|
@ -3,4 +3,5 @@ project(aoc_2021 C)
|
|||
|
||||
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)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,5 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <string.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;
|
||||
int64_t units;
|
||||
|
||||
ret = parse_long(unit_str, &units);
|
||||
ret = parse_long(unit_str, &units, 10);
|
||||
|
||||
if (ret == PARSER_OK) {
|
||||
course_dir_t dir;
|
||||
|
@ -115,6 +113,8 @@ int day_2() {
|
|||
else {
|
||||
printf("Failed to parse data: %d", res);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -22,6 +22,9 @@ int main(int argc, char * argv[]) {
|
|||
case 2:
|
||||
day_2();
|
||||
break;
|
||||
case 3:
|
||||
day_3();
|
||||
break;
|
||||
default:
|
||||
printf("Invalid day ding dong!\n");
|
||||
return -2;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#include <stdio.h>
|
||||
#include "puzzle_input.h"
|
||||
|
||||
parse_ret_t parse_long(char * buffer, int64_t *val) {
|
||||
*val = strtol(buffer, NULL, 10);
|
||||
parse_ret_t parse_long(char * buffer, int64_t *val, int16_t base) {
|
||||
*val = strtol(buffer, NULL, base);
|
||||
|
||||
if (*val == LONG_MIN || *val == LONG_MAX) {
|
||||
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 val;
|
||||
int ret;
|
||||
|
||||
ret = parse_long(buffer, (int64_t *)&val);
|
||||
ret = parse_long(buffer, (int64_t *)&val, base);
|
||||
|
||||
if (ret != PARSER_OK) {
|
||||
return ret;
|
||||
|
@ -31,6 +31,14 @@ parse_ret_t parse_long_from_buff(char * buffer, void * data, uint16_t index) {
|
|||
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) {
|
||||
char buffer[64];
|
||||
int c;
|
||||
|
|
|
@ -16,8 +16,9 @@ parse_ret_t read_input(const char * file_path, void * data, uint16_t max_len, in
|
|||
|
||||
// Parsers
|
||||
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
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue