120 lines
3.2 KiB
C
120 lines
3.2 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include "../lib/util.h"
|
|
|
|
#define HASH_INDEX 1024
|
|
#define HASH_LIST_LENGTH 10
|
|
#define NUMBER_RULES 594
|
|
|
|
typedef struct ValidBags {
|
|
int hash[HASH_INDEX][HASH_LIST_LENGTH];
|
|
int list[NUMBER_RULES];
|
|
size_t index;
|
|
} ValidBags;
|
|
|
|
bool valid_bags_contains(ValidBags *valid_bags, unsigned long h) {
|
|
int *hash_list = valid_bags->hash[h % HASH_INDEX];
|
|
int index = 0;
|
|
while (hash_list[index]) {
|
|
if (hash_list[index] == h) return true;
|
|
index++;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void valid_bags_add(ValidBags *valid_bags, unsigned long h) {
|
|
if (!valid_bags_contains(valid_bags, h)) {
|
|
int *hash_list = valid_bags->hash[h % HASH_INDEX];
|
|
int index = 0;
|
|
while (hash_list[index]) index++;
|
|
hash_list[index] = h;
|
|
}
|
|
}
|
|
|
|
typedef struct BagQuantity {
|
|
int number;
|
|
unsigned long bag_name_hash;
|
|
} BagQuantity;
|
|
|
|
typedef struct BagRule {
|
|
unsigned long bag_name_hash;
|
|
BagQuantity bag_quantities[4];
|
|
} BagRule;
|
|
|
|
void print_bag_rule(BagRule *bag_rule) {
|
|
printf("%u bags contain ", bag_rule->bag_name_hash);
|
|
int bag_quantity_index = 0;
|
|
BagQuantity bag_quantity = bag_rule->bag_quantities[bag_quantity_index];
|
|
while (bag_quantity.number) {
|
|
printf("%d %u bags, ", bag_quantity.number, bag_quantity.bag_name_hash);
|
|
bag_quantity_index++;
|
|
bag_quantity = bag_rule->bag_quantities[bag_quantity_index];
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
void parse_bag_rule(char *bag_rule_string, BagRule *bag_rule) {
|
|
// "light red bags contain 1 bright white bag, 2 muted yellow bags."
|
|
char bag_name_string[30] = {0};
|
|
char *bag_rule_token;
|
|
|
|
bag_rule_token = strtok(bag_rule_string, " "); // rule adjective
|
|
strcpy(bag_name_string, bag_rule_token);
|
|
|
|
bag_rule_token = strtok(NULL, " "); // rule color
|
|
strcat(bag_name_string, bag_rule_token);
|
|
bag_rule->bag_name_hash = hash(bag_name_string);
|
|
|
|
strtok(NULL, " "); // "bags"
|
|
strtok(NULL, " "); // "contain"
|
|
|
|
size_t bag_quantity_index = 0;
|
|
while(bag_rule_token = strtok(NULL, " ")) { // The number is now in the buffer
|
|
bag_rule->bag_quantities[bag_quantity_index].number = atoi(bag_rule_token);
|
|
// printf("number: %d\n", bag_rule->bag_quantities[bag_quantity_index].number );
|
|
|
|
bag_rule_token = strtok(NULL, " "); // rule adjective
|
|
strcpy(bag_name_string, bag_rule_token);
|
|
|
|
bag_rule_token = strtok(NULL, " "); // rule color
|
|
strcat(bag_name_string, bag_rule_token);
|
|
|
|
bag_rule->bag_quantities[bag_quantity_index].bag_name_hash = hash(bag_name_string);
|
|
strtok(NULL, " "); // "bag(s)[.,]"
|
|
|
|
bag_quantity_index++;
|
|
}
|
|
}
|
|
|
|
int part_1() {
|
|
char *data_buffer = load_input();
|
|
char *strtok_ptr = data_buffer;
|
|
|
|
ValidBags valid_bags = {0};
|
|
valid_bags_add(&valid_bags, hash("shinygold"));
|
|
|
|
BagRule *bag_rule = malloc(sizeof(BagRule));
|
|
|
|
char *rule = strtok_r(data_buffer, "\n", &strtok_ptr);
|
|
do {
|
|
parse_bag_rule(rule, bag_rule);
|
|
valid_bags_add(&valid_bags, bag_rule->bag_name_hash);
|
|
// printf("%s\n\n", rule);
|
|
} while(rule = strtok_r(NULL, "\n", &strtok_ptr));
|
|
printf("%d %d %d\n", valid_bags.list[0], valid_bags.list[1], valid_bags.index);
|
|
|
|
free(data_buffer);
|
|
return 0;
|
|
}
|
|
|
|
int part_2() {
|
|
return 0;
|
|
}
|
|
|
|
int main() {
|
|
printf("Part 1: %d\n", part_1());
|
|
printf("Part 2: %d\n", part_2());
|
|
}
|