-
Notifications
You must be signed in to change notification settings - Fork 0
/
day-2.c
136 lines (94 loc) · 3.33 KB
/
day-2.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PART_TWO true
/* maximum possible cube counts corresponding with colours */
uint32_t colour_counts[] = {12, 13, 14};
char *colour_names[] = {"red", "green", "blue"};
#define TOTAL_COLOURS (sizeof(colour_names) / sizeof(char *))
/* determine if a line has cubes that are possible given our defined
* constants */
bool is_roll_possible(char *bag_roll, uint32_t highest_colours[TOTAL_COLOURS]) {
bool roll_possible = true;
char *comma_save = bag_roll;
/* "3 blue", "4 red", etc. */
char *cube_section = strtok_r(comma_save, ",", &comma_save);
while (cube_section != NULL) {
/* skip space */
cube_section++;
int space_position = (int)(strchr(cube_section, ' ') - cube_section);
char cube_count_str[space_position + 1];
strncpy(cube_count_str, cube_section, space_position);
cube_count_str[space_position] = '\0';
uint32_t cube_count = atoi(cube_count_str);
char *cube_colour = cube_section + space_position + 1;
uint32_t colours_possible = 0;
for (size_t i = 0; i < TOTAL_COLOURS; i++) {
if (strcmp(cube_colour, colour_names[i]) == 0) {
if (cube_count > colour_counts[i]) {
roll_possible = false;
}
if (cube_count > highest_colours[i]) {
highest_colours[i] = cube_count;
}
break;
}
}
cube_section = strtok_r(comma_save, ",", &comma_save);
}
return roll_possible;
}
bool is_line_possible(char *line, uint32_t *power) {
/* skip "Game x: " */
while (line[0] != ':') {
line++;
}
line++;
/* the highest rolls for each colour on this line */
uint32_t highest_colours[TOTAL_COLOURS] = {0};
bool line_possible = true;
char *semicolon_save = line;
char *bag_roll = strtok_r(line, ";", &semicolon_save);
while (bag_roll != NULL) {
if (!is_roll_possible(bag_roll, highest_colours)) {
line_possible = false;
}
bag_roll = strtok_r(semicolon_save, ";", &semicolon_save);
}
for (int i = 0; i < TOTAL_COLOURS; i++) {
*power *= highest_colours[i];
}
return line_possible;
}
int main(int argc, char **argv) {
FILE *input_file = fopen("./day-2.txt", "r");
fseek(input_file, 0L, SEEK_END);
/* ignore last newline */
size_t input_size = ftell(input_file) - 1;
rewind(input_file);
char *file_buffer = calloc(input_size, sizeof(char));
fread(file_buffer, sizeof(char), input_size, input_file);
fclose(input_file);
/* sum of game IDs that are possible */
uint32_t game_id_sum = 0;
uint32_t game_id = 1;
/* sum of fewest amounts of cubes needed for each line, multipled
* together */
uint32_t cube_power_sum = 0;
char *line = strtok(file_buffer, "\n");
while (line != NULL) {
uint32_t power = 1;
if (is_line_possible(line, &power)) {
// printf("game %d possible\n", game_id);
game_id_sum += game_id;
}
cube_power_sum += power;
game_id++;
line = strtok(NULL, "\n");
}
printf("%d\n", PART_TWO ? cube_power_sum : game_id_sum);
free(file_buffer);
return 0;
}