#include #include #include #include #include #define ARR_LEN (1000) #define BIT_AMOUNT (12) #define INPUT_FILE ("input.txt") #define BIT_MASK (0xFFF) // read file, dump into diagnostics and count bits void d3_init(int* diagnostics, size_t diag_len, int* bit_ct, size_t bit_ct_len); // return answer for part one int d3_part_one(int* diagnostics, size_t diag_len, int* bit_ct, size_t bit_ct_len); // returns answer for part two int d3_part_two(const int* const diagnostics, size_t diag_len); // if binary we're assuming bit size is 12 because this project is specific to 12 bit numbers static void print_arr(const int* const arr, size_t len, bool binary) { if(binary) { printf("\n"); for(int ind = 0; ind < len; ind++) { printf("[%d]: ", ind); for(int bit = BIT_AMOUNT - 1; bit >= 0; bit--) { printf("%d", ((arr[ind] & (1 << bit))>>bit)); } printf("\n"); } } else { for(int ind = 0; ind < len; ind++) { printf("[%d]: %d\n", ind, arr[ind]); } } } int main(int argc, char** argv) { int diagnostic_arr[ARR_LEN]; int bit_ct[BIT_AMOUNT]; memset(diagnostic_arr, 0, ARR_LEN * sizeof(int)); memset(bit_ct, 0, BIT_AMOUNT * sizeof(int)); d3_init(diagnostic_arr, ARR_LEN, bit_ct, BIT_AMOUNT); int power_consumption = d3_part_one(diagnostic_arr, ARR_LEN, bit_ct, BIT_AMOUNT); printf("(Part 1 Answer) Power Consumption: %d\n", power_consumption); int life_support_rating = d3_part_two(diagnostic_arr, ARR_LEN); printf("(Part 2 Answer) Life support rating: %d\n", life_support_rating); return 0; } // read file, dump into diagnostics and count bits void d3_init(int* diagnostics, size_t diag_len, int* bit_ct, size_t bit_ct_len) { FILE* fp = fopen(INPUT_FILE, "r"); if(!fp) { printf("Failed to open file for reading...\n"); exit(-1); } char* line = NULL; size_t len = 0; for(int ind = 0; ind < ARR_LEN; ind++) { ssize_t rc = getline(&line, &len, fp); if(rc == -1) { printf("EXITING ABNORMALLY\n"); exit(-1); } diagnostics[ind] = strtol(line, NULL, 2); for(int bit = 0; bit < BIT_AMOUNT; bit++) { printf("%d", (diagnostics[ind] & (1<>bit); bit_ct[bit] += ((diagnostics[ind] & (1 << bit))>>bit); } printf("\n"); } fclose(fp); } // returns status of init int d3_part_one(int* diagnostics, size_t diag_len, int* bit_ct, size_t bit_ct_len) { int gamma = 0; int epsilon = 0; for(int bit = 0; bit < bit_ct_len; bit++) { gamma += ((bit_ct[bit] > (ARR_LEN >> 1))<= 0; bit--) { int* ctr_write = &diag_copy[bit%2][ARR_LEN]; int* ctr_read = &diag_copy[~(bit%2) & 0x01][ARR_LEN]; int* diag_write = diag_copy[bit%2]; const int* diag_read = diag_copy[~(bit%2) & 0x01]; memset(diag_write, 0, (sizeof(int) * ARR_LEN) + sizeof(int)); volatile int bit_ct = 0; for(int ind = 0; ind < *ctr_read; ind++) { if((diag_read[ind] >> bit) & 0x01) { bit_ct++; } } for(int ind = 0; ind < *ctr_read; ind++) { if(bit_ct >= (*ctr_read - bit_ct)) { if((diag_read[ind] >> bit) & 0x01) diag_write[(*ctr_write)++] = diag_read[ind]; } else { if(!((diag_read[ind] >> bit) & 0x01)) { diag_write[(*ctr_write)++] = diag_read[ind]; } } } if(*ctr_write <= 1) { printf("found o2 rating\n"); o2_gen_rating = diag_write[*ctr_write-1]; break; } } printf("o2 rating: %d\n", o2_gen_rating); // now we need to do a similar thing for co2 scubber rating // this time we want to find the least common bit instead of most common bit // we copy diagnostics into our second diag_copy arr // this way we start with diag_copy[0] being zeroed // and diag_copy[1] having our original data. // from there we will go back and forth, filtering data // from eachother memcpy(&diag_copy[(~(BIT_AMOUNT - 1)%2) & 0x01], diagnostics, diag_len * sizeof(int)); // last value will be active count, i.e. how many vars are actually in the array diag_copy[(BIT_AMOUNT - 1)%2][ARR_LEN] = 0; diag_copy[(~(BIT_AMOUNT - 1)%2) & 0x01][ARR_LEN] = ARR_LEN; // finding oxygen generator rating for(int bit = BIT_AMOUNT - 1; bit >= 0; bit--) { int* ctr_write = &diag_copy[bit%2][ARR_LEN]; int* ctr_read = &diag_copy[~(bit%2) & 0x01][ARR_LEN]; int* diag_write = diag_copy[bit%2]; const int* diag_read = diag_copy[~(bit%2) & 0x01]; memset(diag_write, 0, (sizeof(int) * ARR_LEN) + sizeof(int)); int bit_ct = 0; for(int ind = 0; ind < *ctr_read; ind++) { if((diag_read[ind] >> bit) & 0x01) { bit_ct++; } } for(int ind = 0; ind < *ctr_read; ind++) { if(bit_ct < (*ctr_read - bit_ct)) { if((diag_read[ind] >> bit) & 0x01) diag_write[(*ctr_write)++] = diag_read[ind]; } else { if(!((diag_read[ind] >> bit) & 0x01)) { diag_write[(*ctr_write)++] = diag_read[ind]; } } } if(*ctr_write <= 1) { printf("found co2 \n"); co2_scrubber_rating = diag_write[*ctr_write-1]; break; } } printf("o2 gen rating: %d\nco2 scrubber rating: %d\n", o2_gen_rating, co2_scrubber_rating); return co2_scrubber_rating * o2_gen_rating; }