-
Notifications
You must be signed in to change notification settings - Fork 0
/
day_six.c
128 lines (117 loc) · 2.67 KB
/
day_six.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
#include <stdio.h>
#include <stdlib.h>
#include "string_utilities.h"
typedef long long int big_int;
#define BIG_INT_FORMAT "%lld"
#define BIG_INT_PARSE(x) atoll(x)
typedef struct {
big_int best_start;
big_int best_end;
} timing;
int count_numbers(char *input) {
int count = 0;
while (*input != '\n') {
if (is_digit(*input)) {
count++;
while (is_digit(*input))
input++;
} else {
input++;
}
}
return count;
}
void collect_numbers(char *input, int total, big_int nums[total]) {
int collected = 0;
while (collected < total) {
input = skip_to_number(input);
nums[collected] = atoi(input);
input = skip_to_tokens(input, " ");
collected++;
}
}
bool meets_distance(big_int wait, big_int time, big_int distance) {
return (wait * (time - wait)) > distance;
}
timing find_best_ends(big_int time, big_int distance) {
// from start
int start = 0;
for (big_int i = 1;i < time;i++) {
if (meets_distance(i, time, distance)) {
start = i;
break;
}
}
// from end
int end = 0;
for (big_int i = time;i > 0;i--) {
if (meets_distance(i, time, distance)) {
end = i;
break;
}
}
timing t = { start, end };
return t;
}
big_int part_a(char *content) {
int total = count_numbers(content);
big_int times[total];
big_int distances[total];
collect_numbers(content, total, times);
content = skip_to_tokens(content, "\n");
content++;
collect_numbers(content, total, distances);
printf("-- Games --\n");
big_int ways = 1;
for (int i = 0;i < total;i++) {
timing ends = find_best_ends(times[i], distances[i]);
big_int diff = ends.best_end - ends.best_start + 1;
ways *= diff;
}
return ways;
}
big_int join_number(char *input) {
// count digits
int digits = 0;
char *df = input;
while (*df != '\n' && *df != '\0') {
if (is_digit(*df))
digits++;
df++;
}
char digits_arr[digits + 1];
char *dar = digits_arr;
df = input;
while (*df != '\n' && *df != '\0') {
if (is_digit(*df)) {
*dar = *df;
dar++;
}
df++;
}
*dar = '\0';
return BIG_INT_PARSE(digits_arr);
}
big_int part_b(char *content) {
big_int time = join_number(content);
content = skip_to_tokens(content, "\n");
content++;
big_int distance = join_number(content);
printf("Time: " BIG_INT_FORMAT ", Distance: " BIG_INT_FORMAT "\n", time, distance);
timing t = find_best_ends(time, distance);
return t.best_end - t.best_start + 1;
}
int main(int argc, char **argv) {
char *contents;
if (argc > 2) {
contents = string_from_file(argv[2]);
} else {
contents = string_from_file("day06ex.txt");
}
if (argc > 1 && argv[1][0] == 'b') {
printf("B Total: " BIG_INT_FORMAT "\n", part_b(contents));
} else {
printf("A Total: " BIG_INT_FORMAT "\n", part_a(contents));
}
free(contents);
}