Skip to content

Commit c714b47

Browse files
authored
feat: day05 c (#8)
1 parent b338faa commit c714b47

File tree

19 files changed

+445
-70
lines changed

19 files changed

+445
-70
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
.vscode
44
/build
55
/perf
6-
Makefile
6+
Makefile
7+
.reponse

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ Ideally, the solution does not use external crates/dependencies.
1515
| 2 |||||||
1616
| 3 |||||||
1717
| 4 |||||||
18-
| 5 ||||| | |
18+
| 5 ||||| | |

c/day03.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static SizeVector create_size_vector(size_t initial_capacity) {
8080

8181
static void push_back(SizeVector *vec, size_t value) {
8282
if (vec->size == vec->capacity) {
83-
vec->capacity = (vec->capacity * 3) / 2; // 1.5x growth
83+
vec->capacity = (vec->capacity * 3) / 2;
8484
vec->data = realloc(vec->data, vec->capacity * sizeof(size_t));
8585
}
8686
vec->data[vec->size++] = value;

c/day04.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
#include <stdlib.h>
44
#include <string.h>
55

6-
// Structure to hold the grid
76
typedef struct {
87
char **data;
98
size_t rows;
109
size_t cols;
1110
} Grid;
1211

13-
// Function to read the file and return a Grid structure
1412
Grid read_file(const char *filename) {
1513
FILE *file = fopen(filename, "r");
1614
if (!file) {
@@ -23,14 +21,12 @@ Grid read_file(const char *filename) {
2321
size_t len = 0;
2422

2523
while (getline(&line, &len, file) != -1) {
26-
// Allocate memory for new row
2724
grid.data = realloc(grid.data, (grid.rows + 1) * sizeof(char *));
2825
grid.data[grid.rows] = strdup(line);
2926
grid.rows++;
3027

31-
// Update columns count if necessary
3228
if (grid.rows == 1) {
33-
grid.cols = strlen(line) - 1; // Exclude newline
29+
grid.cols = strlen(line) - 1;
3430
}
3531
}
3632

@@ -40,16 +36,6 @@ Grid read_file(const char *filename) {
4036
return grid;
4137
}
4238

43-
// Floored division implementation
44-
int floored_division(int a, int b) {
45-
int quotient = a / b;
46-
if ((a % b != 0) && ((a < 0) != (b < 0))) {
47-
return quotient - 1;
48-
}
49-
return quotient;
50-
}
51-
52-
// Count occurrences of a word in all directions in the grid
5339
size_t count_word(const Grid *grid, const char *word) {
5440
size_t count = 0;
5541
int word_len = strlen(word);
@@ -85,7 +71,6 @@ size_t count_word(const Grid *grid, const char *word) {
8571
return count;
8672
}
8773

88-
// Count occurrences of an X-pattern in the grid
8974
size_t count_x_pattern(const Grid *grid, const char *word) {
9075
if (grid->rows == 0) {
9176
fprintf(stderr, "Grid must be a valid grid\n");
@@ -94,10 +79,9 @@ size_t count_x_pattern(const Grid *grid, const char *word) {
9479

9580
size_t count = 0;
9681
int word_len = strlen(word);
97-
int bounded = floored_division(word_len, 2);
82+
int bounded = word_len / 2;
9883
char middle_char = word[bounded];
9984

100-
// Reverse the word
10185
char *reverse_word = strdup(word);
10286
for (int i = 0; i < word_len / 2; i++) {
10387
char temp = reverse_word[i];
@@ -174,11 +158,11 @@ void free_grid(Grid *grid) {
174158
int main() {
175159
Grid grid = read_file("crates/day04/input.txt");
176160

177-
// Part One
161+
// --- Part One ---
178162
size_t count = count_word(&grid, "XMAS");
179163
printf("%zu\n", count);
180164

181-
// Part Two
165+
// --- Part Two ---
182166
count = count_x_pattern(&grid, "MAS");
183167
printf("%zu\n", count);
184168

c/day05.c

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
#include <stdbool.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <string.h>
5+
6+
struct Rule {
7+
int key;
8+
int *values;
9+
int value_count;
10+
};
11+
12+
struct PrintQueueChecker {
13+
struct Rule *rules;
14+
int rule_count;
15+
int **page_numbers;
16+
int *page_numbers_sizes;
17+
int page_numbers_count;
18+
};
19+
20+
static struct Rule *find_rule(struct PrintQueueChecker *checker, int key) {
21+
for (int i = 0; i < checker->rule_count; i++) {
22+
if (checker->rules[i].key == key) {
23+
return &checker->rules[i];
24+
}
25+
}
26+
return NULL;
27+
}
28+
29+
static bool find_value_in_array(const int *arr, int size, int start_idx,
30+
int value) {
31+
for (int i = start_idx; i < size; i++) {
32+
if (arr[i] == value) {
33+
return true;
34+
}
35+
}
36+
return false;
37+
}
38+
39+
static bool check_valid(const struct PrintQueueChecker *checker,
40+
const int *order, int order_size) {
41+
for (int idx = 0; idx < order_size; idx++) {
42+
struct Rule *rule =
43+
find_rule((struct PrintQueueChecker *)checker, order[idx]);
44+
if (rule == NULL)
45+
continue;
46+
47+
for (int j = 0; j < rule->value_count; j++) {
48+
if (find_value_in_array(order, order_size, idx, rule->values[j])) {
49+
return false;
50+
}
51+
}
52+
}
53+
return true;
54+
}
55+
56+
static void parse_puzzle(struct PrintQueueChecker *checker,
57+
const char *puzzle) {
58+
checker->rule_count = 0;
59+
checker->page_numbers_count = 0;
60+
61+
checker->rules = (struct Rule *)malloc(sizeof(struct Rule) * 2000);
62+
for (int i = 0; i < 2000; i++) {
63+
checker->rules[i].values = (int *)malloc(sizeof(int) * 500);
64+
}
65+
66+
checker->page_numbers = (int **)malloc(sizeof(int *) * 500);
67+
checker->page_numbers_sizes = (int *)malloc(sizeof(int) * 500);
68+
69+
char line[2048];
70+
const char *puzzle_ptr = puzzle;
71+
int line_start = 0;
72+
int line_end = 0;
73+
74+
while (puzzle_ptr[line_end] != '\0') {
75+
if (puzzle_ptr[line_end] == '\n' || puzzle_ptr[line_end] == '\0') {
76+
if (line_end - line_start == 0) {
77+
puzzle_ptr += line_end - line_start + 1;
78+
line_start = 0;
79+
line_end = 0;
80+
break;
81+
}
82+
83+
strncpy(line, puzzle_ptr + line_start, line_end - line_start);
84+
line[line_end - line_start] = '\0';
85+
86+
char *delimiter = strchr(line, '|');
87+
if (delimiter != NULL) {
88+
*delimiter = '\0';
89+
int left = atoi(line);
90+
int right = atoi(delimiter + 1);
91+
92+
struct Rule *rule = find_rule(checker, right);
93+
if (rule == NULL) {
94+
rule = &checker->rules[checker->rule_count++];
95+
rule->key = right;
96+
rule->value_count = 0;
97+
}
98+
rule->values[rule->value_count++] = left;
99+
}
100+
101+
puzzle_ptr += line_end - line_start + 1;
102+
line_start = 0;
103+
line_end = 0;
104+
continue;
105+
}
106+
line_end++;
107+
}
108+
109+
while (*puzzle_ptr != '\0') {
110+
while (*puzzle_ptr == '\n')
111+
puzzle_ptr++;
112+
if (*puzzle_ptr == '\0')
113+
break;
114+
115+
int *current_order = (int *)malloc(sizeof(int) * 100);
116+
int current_size = 0;
117+
118+
while (*puzzle_ptr != '\n' && *puzzle_ptr != '\0') {
119+
char number_str[20] = {0};
120+
int i = 0;
121+
122+
while (*puzzle_ptr != ',' && *puzzle_ptr != '\n' && *puzzle_ptr != '\0') {
123+
number_str[i++] = *puzzle_ptr++;
124+
}
125+
126+
current_order[current_size++] = atoi(number_str);
127+
128+
if (*puzzle_ptr == ',')
129+
puzzle_ptr++;
130+
}
131+
132+
checker->page_numbers[checker->page_numbers_count] = current_order;
133+
checker->page_numbers_sizes[checker->page_numbers_count] = current_size;
134+
checker->page_numbers_count++;
135+
136+
if (*puzzle_ptr == '\n')
137+
puzzle_ptr++;
138+
}
139+
}
140+
141+
static int check_page_order(const struct PrintQueueChecker *checker) {
142+
int sum = 0;
143+
for (int i = 0; i < checker->page_numbers_count; i++) {
144+
if (check_valid(checker, checker->page_numbers[i],
145+
checker->page_numbers_sizes[i])) {
146+
sum += checker->page_numbers[i][checker->page_numbers_sizes[i] / 2];
147+
}
148+
}
149+
return sum;
150+
}
151+
152+
static void clone_array(const int *source, int *dest, int size) {
153+
memcpy(dest, source, size * sizeof(int));
154+
}
155+
156+
static int check_and_sort_page_order(const struct PrintQueueChecker *checker) {
157+
int sum = 0;
158+
int *order_clone = (int *)malloc(sizeof(int) * 100);
159+
160+
for (int i = 0; i < checker->page_numbers_count; i++) {
161+
const int *order = checker->page_numbers[i];
162+
int order_size = checker->page_numbers_sizes[i];
163+
164+
if (!check_valid(checker, order, order_size)) {
165+
clone_array(order, order_clone, order_size);
166+
167+
while (!check_valid(checker, order_clone, order_size)) {
168+
bool found_rule_break = false;
169+
int old_idx = 0;
170+
int new_idx = 0;
171+
int replace_val = 0;
172+
173+
for (int idx = 0; idx < order_size && !found_rule_break; idx++) {
174+
struct Rule *rule =
175+
find_rule((struct PrintQueueChecker *)checker, order_clone[idx]);
176+
if (rule == NULL)
177+
continue;
178+
179+
for (int check_idx = order_size - 1; check_idx >= idx; check_idx--) {
180+
for (int rule_idx = 0; rule_idx < rule->value_count; rule_idx++) {
181+
if (order_clone[check_idx] == rule->values[rule_idx]) {
182+
new_idx = check_idx;
183+
found_rule_break = true;
184+
old_idx = idx;
185+
replace_val = order_clone[idx];
186+
break;
187+
}
188+
}
189+
if (found_rule_break)
190+
break;
191+
}
192+
}
193+
194+
if (found_rule_break) {
195+
for (int j = old_idx; j < order_size - 1; j++) {
196+
order_clone[j] = order_clone[j + 1];
197+
}
198+
for (int j = order_size - 1; j > new_idx; j--) {
199+
order_clone[j] = order_clone[j - 1];
200+
}
201+
order_clone[new_idx] = replace_val;
202+
}
203+
}
204+
sum += order_clone[order_size / 2];
205+
}
206+
}
207+
208+
free(order_clone);
209+
return sum;
210+
}
211+
212+
static char *read_file(const char *filename) {
213+
FILE *file = fopen(filename, "r");
214+
if (file == NULL) {
215+
fprintf(stderr, "Unable to open file: %s\n", filename);
216+
exit(1);
217+
}
218+
219+
fseek(file, 0, SEEK_END);
220+
long file_size = ftell(file);
221+
rewind(file);
222+
223+
char *buffer = (char *)malloc(file_size + 1);
224+
if (buffer == NULL) {
225+
fclose(file);
226+
fprintf(stderr, "Memory allocation failed\n");
227+
exit(1);
228+
}
229+
230+
size_t read_size = fread(buffer, 1, file_size, file);
231+
buffer[read_size] = '\0';
232+
233+
fclose(file);
234+
return buffer;
235+
}
236+
237+
static void free_print_queue_checker(struct PrintQueueChecker *checker) {
238+
for (int i = 0; i < checker->rule_count; i++) {
239+
free(checker->rules[i].values);
240+
}
241+
free(checker->rules);
242+
for (int i = 0; i < checker->page_numbers_count; i++) {
243+
free(checker->page_numbers[i]);
244+
}
245+
free(checker->page_numbers);
246+
free(checker->page_numbers_sizes);
247+
}
248+
249+
int main() {
250+
char *message = read_file("crates/day05/input.txt");
251+
struct PrintQueueChecker checker = {0};
252+
253+
parse_puzzle(&checker, message);
254+
255+
// --- Part One ---
256+
printf("Part One solution: %d\n", check_page_order(&checker));
257+
258+
// --- Part Two ---
259+
printf("Part Two solution: %d\n", check_and_sort_page_order(&checker));
260+
261+
free_print_queue_checker(&checker);
262+
free(message);
263+
return 0;
264+
}

0 commit comments

Comments
 (0)