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)
|
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
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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:
|
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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue