Advent of code 2025 (not proud)
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
5#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y))
6typedef struct {
7 long long min;
8 long long max;
9} tuple;
10
11
12tuple* remove_element(tuple* arr,int i,int* len) {
13 for (int j = i; j<*len; j++) {
14 arr[j] = arr[j+1];
15
16 }
17 arr = realloc(arr, (*len-1)*sizeof(tuple));
18 (*len)--;
19 return arr;
20
21}
22
23
24
25int main(int argc, char* argv[]) {
26
27 tuple* limits_arr = NULL;
28 int limits_arr_len = 0;
29
30 FILE* f = NULL;
31 ssize_t nread = 0;
32 size_t size = 0;
33 char* line = NULL;
34 long long start;
35 long long end;
36 long long ingridient;
37 int fresh_ingridients = 0;
38 int fresh = 0;
39 unsigned long long total_fresh_num = 0;
40
41 f = fopen(argv[1], "r");
42
43 while ((nread = getline(&line, &size, f)) > 1) {
44 printf("%s",line);
45
46 // add to the list of min and max values in typle format
47 //
48 start = atoll(strsep(&line, "-"));
49 end = atoll(strsep(&line, "-"));
50 int add_new_entry = 1;
51
52 //check overlaps ~ish~ if new range is bridging two other ranges it still results in overlaps.
53 //however reduces the original amount of ranges.
54 if (limits_arr_len>0) {
55 for (int i = 0; i<limits_arr_len; i++) {
56 if (start<=limits_arr[i].max && start >= limits_arr[i].min) {
57 //[a,start,b],end
58 // if
59 if (end >= limits_arr[i].max) {
60 limits_arr[i].max = end;
61 add_new_entry = 0;
62 break;
63 } else {
64 add_new_entry = 0;
65 break;
66 }
67
68 } else if (start < limits_arr[i].min) {
69 if (end > limits_arr[i].max) {
70 limits_arr[i].max = end;
71 limits_arr[i].min = start;
72 add_new_entry = 0;
73 break;
74 } else if (end<=limits_arr[i].max && end >= limits_arr[i].min) {
75 limits_arr[i].min = start;
76 add_new_entry = 0;
77 break;
78 }
79 }
80 }
81 }
82 if (add_new_entry) {
83 limits_arr_len++;
84 limits_arr = realloc(limits_arr, limits_arr_len*sizeof(tuple));
85
86 limits_arr[limits_arr_len-1].min = start;
87 limits_arr[limits_arr_len-1].max = end;
88 }
89 }
90
91
92 // behold, as i am about to write the worst overlap search algorithm known to humankind.
93 int large_repeat = 0;
94
95 do {
96
97 large_repeat = 0;
98 // as long as we do mergets, we run the whole thing again.
99
100 for (int i = 0; i<limits_arr_len; i++) { // limit_arr_len will be changing as this goes i have no idea if this is optimal
101 start = limits_arr[i].min;
102 end = limits_arr[i].max;
103 int repeat = 0; // if a merge happened, we will set repeat to true, and so will run the cycle again to check for new overlaps
104 do {
105 repeat = 0;
106 for (int j = i+1; j<limits_arr_len; j++) {
107 //this is horrible
108 // we go over every entry in limit_arr.
109 // if another entry has one of the ends inside, we set the other end equal to the appropriate value, whichever gives the largest range.
110 // then delete it.
111 if (limits_arr[j].min >= start && limits_arr[j].min <= end) {
112 limits_arr[i].max = MAX(end, limits_arr[j].max);
113 limits_arr = remove_element(limits_arr, j, &limits_arr_len);
114 repeat = 1;
115 large_repeat = 1;
116 j--;
117 }
118 else if (limits_arr[j].max >= start && limits_arr[j].max <= end) {
119 limits_arr[i].min = MIN(start, limits_arr[j].min);
120 limits_arr = remove_element(limits_arr, j, &limits_arr_len);
121 repeat = 1;
122 large_repeat = 1;
123 j--;
124 }
125 else if (limits_arr[j].min <= start && limits_arr[j].max >= end) {
126 limits_arr[i] = limits_arr[j];
127 limits_arr = remove_element(limits_arr, j, &limits_arr_len);
128 repeat = 1;
129 large_repeat = 1;
130 j--;
131 }
132 }
133 }while (repeat);
134 }
135
136
137 }while(large_repeat);
138
139
140
141
142
143
144 for (int i = 0; i<limits_arr_len; i++) {
145 total_fresh_num += limits_arr[i].max - limits_arr[i].min +1;
146 printf("min %lld, max %lld, num: %lld\n",limits_arr[i].min,limits_arr[i].max,(limits_arr[i].max - limits_arr[i].min +1));
147 }
148
149 //not we go through ingridients
150
151 while ((nread = getline(&line, &size, f)) != -1) {
152 printf("%s",line);
153 fresh = 0;
154 ingridient = atoll(line);
155 for (int i = 0; i<limits_arr_len; i++) {
156 if (ingridient >= limits_arr[i].min && ingridient <= limits_arr[i].max) {
157 fresh= 1;
158 fresh_ingridients++;
159 // printf("ingridient %lld is fresh in range %lld-%lld\n", ingridient,limits_arr[i].min,limits_arr[i].max);
160 break;
161 }
162 }
163
164 }
165
166
167
168 printf("total %d fresh ingridients",fresh_ingridients);
169 printf("total fresh ingridients possible: %lld\n",total_fresh_num);
170
171 free(limits_arr);
172
173 free(f);
174 free(line);
175
176
177 return 0;
178}