131 lines
2.5 KiB
C
131 lines
2.5 KiB
C
#include "lib.h"
|
|
|
|
#define DBG 0
|
|
|
|
static
|
|
unsigned char input[] = {
|
|
#embed "day2_input.txt"
|
|
};
|
|
|
|
static
|
|
unsigned char test[] = {
|
|
#embed "day2_test.txt"
|
|
};
|
|
|
|
uint64_t ipow(uint64_t a, uint64_t b) {
|
|
uint64_t m = a;
|
|
for (;b;b--) m += a;
|
|
return m;
|
|
}
|
|
|
|
static
|
|
uint64_t range(uint64_t start, uint64_t end, uint64_t len) {
|
|
#if DBG
|
|
print("==\n");
|
|
printd(start); print(" "); printd(end); print("\n");
|
|
#endif
|
|
|
|
if ((len & 1) == 1) {
|
|
return 0;
|
|
}
|
|
|
|
uint64_t divisor = ipow(10, len / 2);
|
|
|
|
uint64_t first = (start + divisor - 1) / divisor;
|
|
uint64_t second = end / divisor;
|
|
|
|
#if DBG
|
|
print("\n");
|
|
printd(divisor); print("\n");
|
|
printd(first); print(" "); printd(second); print("\n");
|
|
#endif
|
|
|
|
uint64_t r = (((second + first) * (second + 1 - first)) / 2) * divisor;
|
|
|
|
#if DBG
|
|
printd(r); print("\n");
|
|
#endif
|
|
|
|
return r;
|
|
}
|
|
|
|
static
|
|
uint64_t do_part1(size_t file_len, unsigned char file[file_len]) {
|
|
unsigned char buffer[65535];
|
|
memcpy(buffer, file, file_len);
|
|
size_t size = file_len;
|
|
buffer[file_len-1] = ',';
|
|
|
|
uint64_t out = 0;
|
|
uint64_t i = 0;
|
|
|
|
while (i < size) {
|
|
#if DBG
|
|
print("--------------\n");
|
|
#endif
|
|
uint64_t startlen = 0, endlen = 0;
|
|
uint64_t start = grabnum(buffer+i, NULL);
|
|
|
|
while (buffer[i] != '-') {
|
|
i++;
|
|
startlen++;
|
|
}
|
|
i++;
|
|
|
|
uint64_t end = grabnum(buffer+i, NULL);
|
|
|
|
while (buffer[i] != ',') {
|
|
i++;
|
|
endlen++;
|
|
}
|
|
i++;
|
|
|
|
#if DBG
|
|
printd(startlen); print(" "); printd(start); print((char[]){ 10 });
|
|
printd(startlen); print(" "); printd(start); print((char[]){ 10 });
|
|
#endif
|
|
|
|
if (endlen != startlen) {
|
|
out += range(start, ipow(10, startlen) - 1, startlen)
|
|
+ range(ipow(10, startlen), end, endlen);
|
|
} else {
|
|
out += range(start, end, startlen);
|
|
}
|
|
|
|
#if DBG
|
|
print((char[]) { 10 });
|
|
#endif
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
#define RUN_TEST1 1
|
|
#define RUN_PART1 1
|
|
|
|
#define TEST1_EXPECT 0x1227775554l
|
|
|
|
void run() {
|
|
volatile uintptr_t s = (uintptr_t)&s;
|
|
printh(s);
|
|
print("\n");
|
|
#if RUN_TEST1
|
|
print("PART 1 TEST: ");
|
|
if (uint64_t v = do_part1(countof(test), test); v != TEST1_EXPECT) {
|
|
print("FAILED (got ");
|
|
printd(v);
|
|
print(", expected " xstr(TEST1_EXPECT) ")\n");
|
|
} else {
|
|
print("PASSED\n");
|
|
}
|
|
#endif
|
|
|
|
#if RUN_PART1
|
|
print("PART 1 RESULT: ");
|
|
printd(do_part1(countof(input), input));
|
|
print("\n");
|
|
#endif
|
|
|
|
exit_group(0);
|
|
}
|