day 4
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
*.txt
|
*.txt
|
||||||
*.elf
|
*.elf
|
||||||
|
*.o
|
||||||
blink.log
|
blink.log
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
|||||||
23
Makefile
23
Makefile
@@ -2,14 +2,27 @@ FILES = $(wildcard ./*)
|
|||||||
SRCS = $(filter %.c,$(FILES))
|
SRCS = $(filter %.c,$(FILES))
|
||||||
BINS = $(SRCS:%.c=%.elf)
|
BINS = $(SRCS:%.c=%.elf)
|
||||||
|
|
||||||
CFLAGS = -Wall -Werror -pedantic -Wno-unused -D_GNU_SOURCE -std=gnu2y\
|
MUSLFILES = $(wildcard ./musl/*)
|
||||||
-O3 -g -Ttext=C475000 -static -nostartfiles -fno-stack-protector\
|
MUSLSRCS = $(filter %.s,$(MUSLFILES))
|
||||||
-march=x86-64 -msse2 -msse3 -mssse3 -mpclmul -mpopcnt -madx -mbmi2 -mrdrnd -mrdseed
|
MUSLOBJS = $(MUSLSRCS:%.s=%.o)
|
||||||
|
|
||||||
|
CFLAGS = -Wall -Werror -pedantic -Wno-unused -std=gnu2y\
|
||||||
|
-O3 -c -g -fno-stack-protector -fno-pie\
|
||||||
|
-fno-semantic-interposition -fno-trapping-math\
|
||||||
|
-march=x86-64 -mprefer-vector-width=128 -mpopcnt -malign-data=compat -malign-stringops
|
||||||
|
|
||||||
|
LFLAGS = -Ttext=C475000 -static -nostdlib -no-pie
|
||||||
|
|
||||||
all: $(BINS)
|
all: $(BINS)
|
||||||
|
|
||||||
%.elf: %.c
|
%.elf: %.o start.o | %.c lib.h $(MUSLOBJS)
|
||||||
|
ld -o $@ $(LFLAGS) start.o $< $(MUSLOBJS)
|
||||||
|
|
||||||
|
start.o: start.s
|
||||||
|
nasm -f elf64 -o $@ $<
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
gcc-tree -o $@ $(CFLAGS) $<
|
gcc-tree -o $@ $(CFLAGS) $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm ./*.elf
|
rm -f *.elf *.o
|
||||||
|
|||||||
92
day0.h
Normal file
92
day0.h
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
#include "lib.h"
|
||||||
|
|
||||||
|
#define DBG 0
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned char input[] = {
|
||||||
|
#embed "day0_input.txt"
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned char test[] = {
|
||||||
|
#embed "day0_test.txt"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned long do_part1(size_t file_len, unsigned char file[file_len]) {
|
||||||
|
unsigned char *s = file;
|
||||||
|
unsigned long result = 0;
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
print("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
do {
|
||||||
|
s++;
|
||||||
|
} while (s != &file[file_len]);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned long do_part2(size_t file_len, unsigned char file[file_len]) {
|
||||||
|
unsigned char *s = file;
|
||||||
|
unsigned long result = 0;
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
print("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
do {
|
||||||
|
s++;
|
||||||
|
} while (s != &file[file_len]);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RUN_TEST1 1
|
||||||
|
#define RUN_PART1 0
|
||||||
|
#define RUN_TEST2 0
|
||||||
|
#define RUN_PART2 0
|
||||||
|
|
||||||
|
#define TEST1_EXPECT -1
|
||||||
|
#define TEST2_EXPECT -1
|
||||||
|
|
||||||
|
void run() {
|
||||||
|
#if RUN_TEST1
|
||||||
|
print("PART 1 TEST: ");
|
||||||
|
if (unsigned long 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
|
||||||
|
|
||||||
|
#if RUN_TEST2
|
||||||
|
print("PART 2 TEST: ");
|
||||||
|
if (unsigned long v = do_part2(countof(test), test); v != TEST2_EXPECT) {
|
||||||
|
print("FAILED (got ");
|
||||||
|
printd(v);
|
||||||
|
print(", expected " xstr(TEST2_EXPECT) ")\n");
|
||||||
|
} else {
|
||||||
|
print("PASSED\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if RUN_PART2
|
||||||
|
print("PART 2 RESULT: ");
|
||||||
|
printd(do_part2(countof(input), input));
|
||||||
|
print("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
exit_group(0);
|
||||||
|
}
|
||||||
67
day1.c
67
day1.c
@@ -1,4 +1,65 @@
|
|||||||
#include "lib.h"
|
#include <stdlib.h>
|
||||||
|
#include <stdcountof.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define SYS_write 1
|
||||||
|
#define SYS_exit_group 231
|
||||||
|
|
||||||
|
#define STDOUT_FILENO 1
|
||||||
|
|
||||||
|
static
|
||||||
|
void write(uint64_t fileno, void *buffer, size_t len) {
|
||||||
|
uint64_t a,d;
|
||||||
|
asm volatile("syscall"
|
||||||
|
:"=a"(a),"=d"(d):"a"(SYS_write),"D"(fileno),"S"(buffer),"d"(len):"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[noreturn]] static
|
||||||
|
void exit_group() {
|
||||||
|
asm volatile(
|
||||||
|
"syscall\n"
|
||||||
|
"ud2"
|
||||||
|
::"a"(SYS_exit_group),"D"(0));
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define xstr(s) str(s)
|
||||||
|
#define str(s) #s
|
||||||
|
|
||||||
|
static
|
||||||
|
void print_many_char(size_t len, char chars[len]) {
|
||||||
|
write(STDOUT_FILENO, chars, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define print(string) print_many_char(sizeof(string)-1, string)
|
||||||
|
|
||||||
|
static
|
||||||
|
void printd(unsigned long v) {
|
||||||
|
if (!v) {
|
||||||
|
print("0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char buf[32];
|
||||||
|
char *p = buf+32;
|
||||||
|
unsigned count = 0;
|
||||||
|
while (v) {
|
||||||
|
p--;
|
||||||
|
*p = '0' + (v % 10);
|
||||||
|
v /= 10;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
write(STDOUT_FILENO, p, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned grabnum(const char *s, const char **end) {
|
||||||
|
unsigned r = 0;
|
||||||
|
for (; *s >= '0' && *s <= '9'; s++)
|
||||||
|
r = r * 10 + (*s - '0');
|
||||||
|
*end = s;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
#define DBG 1
|
#define DBG 1
|
||||||
|
|
||||||
@@ -74,7 +135,7 @@ unsigned do_part2(size_t src_len, const char src[src_len]) {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _start() {
|
void run() {
|
||||||
#if RUN_TEST1
|
#if RUN_TEST1
|
||||||
print("PART 1 TEST: ");
|
print("PART 1 TEST: ");
|
||||||
if (unsigned long v = do_part1(countof(test), test); v != TEST1_EXPECT) {
|
if (unsigned long v = do_part1(countof(test), test); v != TEST1_EXPECT) {
|
||||||
@@ -109,5 +170,5 @@ void _start() {
|
|||||||
print("\n");
|
print("\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
syscall(SYS_exit_group, 0);
|
exit_group();
|
||||||
}
|
}
|
||||||
|
|||||||
8
day2.c
8
day2.c
@@ -251,13 +251,13 @@ no_len_change:
|
|||||||
|
|
||||||
#define RUN_TEST1 1
|
#define RUN_TEST1 1
|
||||||
#define RUN_PART1 1
|
#define RUN_PART1 1
|
||||||
#define RUN_TEST2 1
|
#define RUN_TEST2 0
|
||||||
#define RUN_PART2 1
|
#define RUN_PART2 0
|
||||||
|
|
||||||
#define TEST1_EXPECT 0x1227775554l
|
#define TEST1_EXPECT 0x1227775554l
|
||||||
#define TEST2_EXPECT 0x4174379265l
|
#define TEST2_EXPECT 0x4174379265l
|
||||||
|
|
||||||
void _start() {
|
void run() {
|
||||||
#if RUN_TEST1
|
#if RUN_TEST1
|
||||||
print("PART 1 TEST: ");
|
print("PART 1 TEST: ");
|
||||||
if (bcdint v = do_part1(countof(test), test); v != TEST1_EXPECT) {
|
if (bcdint v = do_part1(countof(test), test); v != TEST1_EXPECT) {
|
||||||
@@ -292,5 +292,5 @@ void _start() {
|
|||||||
print("\n");
|
print("\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
syscall(SYS_exit_group, 0);
|
exit_group(0);
|
||||||
}
|
}
|
||||||
|
|||||||
130
day2_plasl.c
Normal file
130
day2_plasl.c
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#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);
|
||||||
|
}
|
||||||
14
day3.c
14
day3.c
@@ -8,7 +8,7 @@ unsigned char input[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
unsigned char test[] = {
|
unsigned char test_input[] = {
|
||||||
#embed "day3_test.txt"
|
#embed "day3_test.txt"
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -78,15 +78,15 @@ unsigned long do_part2(size_t file_len, unsigned char file[file_len]) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RUN_TEST1 1
|
#define RUN_TEST1 0
|
||||||
#define RUN_PART1 1
|
#define RUN_PART1 0
|
||||||
#define RUN_TEST2 1
|
#define RUN_TEST2 1
|
||||||
#define RUN_PART2 1
|
#define RUN_PART2 1
|
||||||
|
|
||||||
#define TEST1_EXPECT 357
|
#define TEST1_EXPECT 357
|
||||||
#define TEST2_EXPECT 3121910778619
|
#define TEST2_EXPECT 3121910778619l
|
||||||
|
|
||||||
void _start() {
|
void run() {
|
||||||
#if RUN_TEST1
|
#if RUN_TEST1
|
||||||
print("PART 1 TEST: ");
|
print("PART 1 TEST: ");
|
||||||
if (unsigned long v = do_part1(countof(test), test); v != TEST1_EXPECT) {
|
if (unsigned long v = do_part1(countof(test), test); v != TEST1_EXPECT) {
|
||||||
@@ -106,7 +106,7 @@ void _start() {
|
|||||||
|
|
||||||
#if RUN_TEST2
|
#if RUN_TEST2
|
||||||
print("PART 2 TEST: ");
|
print("PART 2 TEST: ");
|
||||||
if (unsigned long v = do_part2(countof(test), test); v != TEST2_EXPECT) {
|
if (unsigned long v = do_part2(countof(test_input), test_input); v != TEST2_EXPECT) {
|
||||||
print("FAILED (got ");
|
print("FAILED (got ");
|
||||||
printd(v);
|
printd(v);
|
||||||
print(", expected " xstr(TEST2_EXPECT) ")\n");
|
print(", expected " xstr(TEST2_EXPECT) ")\n");
|
||||||
@@ -121,5 +121,5 @@ void _start() {
|
|||||||
print("\n");
|
print("\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
syscall(SYS_exit_group, 0);
|
exit_group(0);
|
||||||
}
|
}
|
||||||
|
|||||||
207
day4.c
Normal file
207
day4.c
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
#include "lib.h"
|
||||||
|
|
||||||
|
#define DBG 0
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned char input[] = {
|
||||||
|
#embed "day4_input.txt"
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned char test[] = {
|
||||||
|
#embed "day4_test.txt"
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned char buf[UINT16_MAX];
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned long do_part1(size_t file_len, unsigned char file[file_len]) {
|
||||||
|
unsigned char *s = file, *d = buf;
|
||||||
|
unsigned long result = 0;
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
print("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned file_stride;
|
||||||
|
while (*s != '\n') s++;
|
||||||
|
file_stride = s - file + 1;
|
||||||
|
s = file;
|
||||||
|
|
||||||
|
unsigned line_count = file_len / file_stride;
|
||||||
|
|
||||||
|
unsigned line_stride = file_stride + 1;
|
||||||
|
|
||||||
|
memset(d, '0', sizeof(buf));
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
printh(file_stride); print("\n");
|
||||||
|
printh(line_stride * (line_count + 2)); print("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
printns(line_stride, d); print("\n");
|
||||||
|
#endif
|
||||||
|
d += line_stride;
|
||||||
|
do {
|
||||||
|
memcpy(d + 1, s, file_stride - 1);
|
||||||
|
#if DBG
|
||||||
|
printns(line_stride, d); print("\n");
|
||||||
|
#endif
|
||||||
|
d += line_stride;
|
||||||
|
s += file_stride;
|
||||||
|
} while (s != &file[file_len]);
|
||||||
|
#if DBG
|
||||||
|
printns(line_stride, d); print("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned char *l = buf + line_stride + 1;
|
||||||
|
for (unsigned i = line_count; i; i--) {
|
||||||
|
d = l;
|
||||||
|
for (unsigned j = line_stride - 2; j; j--) {
|
||||||
|
if (*d == '@') {
|
||||||
|
unsigned neighbors = 0
|
||||||
|
+ (*(d - 1 - line_stride) == '@')
|
||||||
|
+ (*(d - 0 - line_stride) == '@')
|
||||||
|
+ (*(d + 1 - line_stride) == '@')
|
||||||
|
+ (*(d - 1 - 0) == '@')
|
||||||
|
+ (*(d + 1 - 0) == '@')
|
||||||
|
+ (*(d - 1 + line_stride) == '@')
|
||||||
|
+ (*(d - 0 + line_stride) == '@')
|
||||||
|
+ (*(d + 1 + line_stride) == '@');
|
||||||
|
if (neighbors < 4) {
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
l += line_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
unsigned long do_part2(size_t file_len, unsigned char file[file_len]) {
|
||||||
|
unsigned char *s = file, *d = buf;
|
||||||
|
unsigned long result = 0;
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
print("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned file_stride;
|
||||||
|
while (*s != '\n') s++;
|
||||||
|
file_stride = s - file + 1;
|
||||||
|
s = file;
|
||||||
|
|
||||||
|
unsigned line_count = file_len / file_stride;
|
||||||
|
|
||||||
|
unsigned line_stride = file_stride + 1;
|
||||||
|
|
||||||
|
memset(d, '0', sizeof(buf));
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
printh(file_stride); print("\n");
|
||||||
|
printh(line_stride * (line_count + 2)); print("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DBG
|
||||||
|
printns(line_stride, d); print("\n");
|
||||||
|
#endif
|
||||||
|
d += line_stride;
|
||||||
|
do {
|
||||||
|
memcpy(d + 1, s, file_stride - 1);
|
||||||
|
#if DBG
|
||||||
|
printns(line_stride, d); print("\n");
|
||||||
|
#endif
|
||||||
|
d += line_stride;
|
||||||
|
s += file_stride;
|
||||||
|
} while (s != &file[file_len]);
|
||||||
|
#if DBG
|
||||||
|
printns(line_stride, d); print("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
unsigned char *l = buf + line_stride + 1;
|
||||||
|
for (unsigned i = line_count; i; i--) {
|
||||||
|
line_start:
|
||||||
|
d = l;
|
||||||
|
for (unsigned j = line_stride - 2; j; j--) {
|
||||||
|
if (*d == '@') {
|
||||||
|
unsigned neighbors = 0
|
||||||
|
+ (*(d - 1 - line_stride) == '@')
|
||||||
|
+ (*(d - 0 - line_stride) == '@')
|
||||||
|
+ (*(d + 1 - line_stride) == '@')
|
||||||
|
+ (*(d - 1 - 0) == '@')
|
||||||
|
+ (*(d + 1 - 0) == '@')
|
||||||
|
+ (*(d - 1 + line_stride) == '@')
|
||||||
|
+ (*(d - 0 + line_stride) == '@')
|
||||||
|
+ (*(d + 1 + line_stride) == '@');
|
||||||
|
if (neighbors < 4) {
|
||||||
|
*d = '.';
|
||||||
|
result++;
|
||||||
|
if (i > line_count-1) {
|
||||||
|
i = line_count;
|
||||||
|
l = buf + line_stride + 1;
|
||||||
|
goto line_start;
|
||||||
|
} else {
|
||||||
|
i += 1;
|
||||||
|
l -= line_stride * 1;
|
||||||
|
goto line_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
l += line_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RUN_TEST1 1
|
||||||
|
#define RUN_PART1 1
|
||||||
|
#define RUN_TEST2 1
|
||||||
|
#define RUN_PART2 1
|
||||||
|
|
||||||
|
#define TEST1_EXPECT 13
|
||||||
|
#define TEST2_EXPECT 43
|
||||||
|
|
||||||
|
void run() {
|
||||||
|
#if RUN_TEST1
|
||||||
|
print("PART 1 TEST: ");
|
||||||
|
if (unsigned long 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
|
||||||
|
|
||||||
|
#if RUN_TEST2
|
||||||
|
print("PART 2 TEST: ");
|
||||||
|
if (unsigned long v = do_part2(countof(test), test); v != TEST2_EXPECT) {
|
||||||
|
print("FAILED (got ");
|
||||||
|
printd(v);
|
||||||
|
print(", expected " xstr(TEST2_EXPECT) ")\n");
|
||||||
|
} else {
|
||||||
|
print("PASSED\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if RUN_PART2
|
||||||
|
print("PART 2 RESULT: ");
|
||||||
|
printd(do_part2(countof(input), input));
|
||||||
|
print("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
exit_group(0);
|
||||||
|
}
|
||||||
43
lib.h
43
lib.h
@@ -1,11 +1,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdlib.h>
|
#include <stddef.h>
|
||||||
#include <stdcountof.h>
|
#include <stdcountof.h>
|
||||||
#include <sys/syscall.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#define SYS_write 1
|
||||||
|
#define SYS_exit_group 231
|
||||||
|
|
||||||
|
#define STDOUT_FILENO 1
|
||||||
|
|
||||||
|
static
|
||||||
|
void write(uint64_t fileno, void *buffer, size_t len) {
|
||||||
|
uint64_t a,d;
|
||||||
|
asm volatile("syscall"
|
||||||
|
:"=a"(a),"=d"(d):"a"(SYS_write),"D"(fileno),"S"(buffer),"d"(len):"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[noreturn]] static
|
||||||
|
void exit_group(uint64_t code) {
|
||||||
|
asm volatile(
|
||||||
|
"syscall\n"
|
||||||
|
"ud2"
|
||||||
|
::"a"(SYS_exit_group),"D"(code));
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
|
||||||
#define xstr(s) str(s)
|
#define xstr(s) str(s)
|
||||||
#define str(s) #s
|
#define str(s) #s
|
||||||
|
|
||||||
@@ -13,7 +32,7 @@ typedef uint64_t bcdint;
|
|||||||
|
|
||||||
static
|
static
|
||||||
void printns(size_t len, unsigned char chars[len]) {
|
void printns(size_t len, unsigned char chars[len]) {
|
||||||
syscall(SYS_write, STDOUT_FILENO, chars, len);
|
write(STDOUT_FILENO, chars, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@@ -29,12 +48,12 @@ void printptr(uintptr_t v) {
|
|||||||
}
|
}
|
||||||
v >>= 4;
|
v >>= 4;
|
||||||
}
|
}
|
||||||
syscall(SYS_write, STDOUT_FILENO, p, countof(buf));
|
write(STDOUT_FILENO, p, countof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void print_many_char(size_t len, char chars[len]) {
|
void print_many_char(size_t len, char chars[len]) {
|
||||||
syscall(SYS_write, STDOUT_FILENO, chars, len);
|
write(STDOUT_FILENO, chars, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define print(string) print_many_char(sizeof(string)-1, string)
|
#define print(string) print_many_char(sizeof(string)-1, string)
|
||||||
@@ -54,7 +73,7 @@ void printd(unsigned long v) {
|
|||||||
v /= 10;
|
v /= 10;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
syscall(SYS_write, STDOUT_FILENO, p, count);
|
write(STDOUT_FILENO, p, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@@ -76,7 +95,7 @@ void printh(unsigned long v) {
|
|||||||
v >>= 4;
|
v >>= 4;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
syscall(SYS_write, STDOUT_FILENO, p, count);
|
write(STDOUT_FILENO, p, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@@ -95,7 +114,7 @@ void print_hex_char(unsigned char v) {
|
|||||||
buf[1] = 'A' - 0xA + (v & 0x0F);
|
buf[1] = 'A' - 0xA + (v & 0x0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
syscall(SYS_write, STDOUT_FILENO, buf, sizeof(buf));
|
write(STDOUT_FILENO, buf, sizeof(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@@ -125,11 +144,11 @@ bcdint grabbcd(unsigned char *s, unsigned char **end) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
unsigned grabnum(const char *s, const char **end) {
|
unsigned long grabnum(unsigned char *s, unsigned char **end) {
|
||||||
unsigned r = 0;
|
unsigned long r = 0;
|
||||||
for (; *s >= '0' && *s <= '9'; s++)
|
for (; *s >= '0' && *s <= '9'; s++)
|
||||||
r = r * 10 + (*s - '0');
|
r = r * 10 + (*s - '0');
|
||||||
*end = s;
|
if (end) *end = s;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
193
musl/COPYRIGHT
Normal file
193
musl/COPYRIGHT
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
musl as a whole is licensed under the following standard MIT license:
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
Copyright © 2005-2020 Rich Felker, et al.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Authors/contributors include:
|
||||||
|
|
||||||
|
A. Wilcox
|
||||||
|
Ada Worcester
|
||||||
|
Alex Dowad
|
||||||
|
Alex Suykov
|
||||||
|
Alexander Monakov
|
||||||
|
Andre McCurdy
|
||||||
|
Andrew Kelley
|
||||||
|
Anthony G. Basile
|
||||||
|
Aric Belsito
|
||||||
|
Arvid Picciani
|
||||||
|
Bartosz Brachaczek
|
||||||
|
Benjamin Peterson
|
||||||
|
Bobby Bingham
|
||||||
|
Boris Brezillon
|
||||||
|
Brent Cook
|
||||||
|
Chris Spiegel
|
||||||
|
Clément Vasseur
|
||||||
|
Daniel Micay
|
||||||
|
Daniel Sabogal
|
||||||
|
Daurnimator
|
||||||
|
David Carlier
|
||||||
|
David Edelsohn
|
||||||
|
Denys Vlasenko
|
||||||
|
Dmitry Ivanov
|
||||||
|
Dmitry V. Levin
|
||||||
|
Drew DeVault
|
||||||
|
Emil Renner Berthing
|
||||||
|
Fangrui Song
|
||||||
|
Felix Fietkau
|
||||||
|
Felix Janda
|
||||||
|
Gianluca Anzolin
|
||||||
|
Hauke Mehrtens
|
||||||
|
He X
|
||||||
|
Hiltjo Posthuma
|
||||||
|
Isaac Dunham
|
||||||
|
Jaydeep Patil
|
||||||
|
Jens Gustedt
|
||||||
|
Jeremy Huntwork
|
||||||
|
Jo-Philipp Wich
|
||||||
|
Joakim Sindholt
|
||||||
|
John Spencer
|
||||||
|
Julien Ramseier
|
||||||
|
Justin Cormack
|
||||||
|
Kaarle Ritvanen
|
||||||
|
Khem Raj
|
||||||
|
Kylie McClain
|
||||||
|
Leah Neukirchen
|
||||||
|
Luca Barbato
|
||||||
|
Luka Perkov
|
||||||
|
Lynn Ochs
|
||||||
|
M Farkas-Dyck (Strake)
|
||||||
|
Mahesh Bodapati
|
||||||
|
Markus Wichmann
|
||||||
|
Masanori Ogino
|
||||||
|
Michael Clark
|
||||||
|
Michael Forney
|
||||||
|
Mikhail Kremnyov
|
||||||
|
Natanael Copa
|
||||||
|
Nicholas J. Kain
|
||||||
|
orc
|
||||||
|
Pascal Cuoq
|
||||||
|
Patrick Oppenlander
|
||||||
|
Petr Hosek
|
||||||
|
Petr Skocik
|
||||||
|
Pierre Carrier
|
||||||
|
Reini Urban
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Ryan Fairfax
|
||||||
|
Samuel Holland
|
||||||
|
Segev Finer
|
||||||
|
Shiz
|
||||||
|
sin
|
||||||
|
Solar Designer
|
||||||
|
Stefan Kristiansson
|
||||||
|
Stefan O'Rear
|
||||||
|
Szabolcs Nagy
|
||||||
|
Timo Teräs
|
||||||
|
Trutz Behn
|
||||||
|
Will Dietz
|
||||||
|
William Haddon
|
||||||
|
William Pitcock
|
||||||
|
|
||||||
|
Portions of this software are derived from third-party works licensed
|
||||||
|
under terms compatible with the above MIT license:
|
||||||
|
|
||||||
|
The TRE regular expression implementation (src/regex/reg* and
|
||||||
|
src/regex/tre*) is Copyright © 2001-2008 Ville Laurikari and licensed
|
||||||
|
under a 2-clause BSD license (license text in the source files). The
|
||||||
|
included version has been heavily modified by Rich Felker in 2012, in
|
||||||
|
the interests of size, simplicity, and namespace cleanliness.
|
||||||
|
|
||||||
|
Much of the math library code (src/math/* and src/complex/*) is
|
||||||
|
Copyright © 1993,2004 Sun Microsystems or
|
||||||
|
Copyright © 2003-2011 David Schultz or
|
||||||
|
Copyright © 2003-2009 Steven G. Kargl or
|
||||||
|
Copyright © 2003-2009 Bruce D. Evans or
|
||||||
|
Copyright © 2008 Stephen L. Moshier or
|
||||||
|
Copyright © 2017-2018 Arm Limited
|
||||||
|
and labelled as such in comments in the individual source files. All
|
||||||
|
have been licensed under extremely permissive terms.
|
||||||
|
|
||||||
|
The ARM memcpy code (src/string/arm/memcpy.S) is Copyright © 2008
|
||||||
|
The Android Open Source Project and is licensed under a two-clause BSD
|
||||||
|
license. It was taken from Bionic libc, used on Android.
|
||||||
|
|
||||||
|
The AArch64 memcpy and memset code (src/string/aarch64/*) are
|
||||||
|
Copyright © 1999-2019, Arm Limited.
|
||||||
|
|
||||||
|
The implementation of DES for crypt (src/crypt/crypt_des.c) is
|
||||||
|
Copyright © 1994 David Burren. It is licensed under a BSD license.
|
||||||
|
|
||||||
|
The implementation of blowfish crypt (src/crypt/crypt_blowfish.c) was
|
||||||
|
originally written by Solar Designer and placed into the public
|
||||||
|
domain. The code also comes with a fallback permissive license for use
|
||||||
|
in jurisdictions that may not recognize the public domain.
|
||||||
|
|
||||||
|
The smoothsort implementation (src/stdlib/qsort.c) is Copyright © 2011
|
||||||
|
Lynn Ochs and is licensed under an MIT-style license.
|
||||||
|
|
||||||
|
The x86_64 port was written by Nicholas J. Kain and is licensed under
|
||||||
|
the standard MIT terms.
|
||||||
|
|
||||||
|
The mips and microblaze ports were originally written by Richard
|
||||||
|
Pennington for use in the ellcc project. The original code was adapted
|
||||||
|
by Rich Felker for build system and code conventions during upstream
|
||||||
|
integration. It is licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The mips64 port was contributed by Imagination Technologies and is
|
||||||
|
licensed under the standard MIT terms.
|
||||||
|
|
||||||
|
The powerpc port was also originally written by Richard Pennington,
|
||||||
|
and later supplemented and integrated by John Spencer. It is licensed
|
||||||
|
under the standard MIT terms.
|
||||||
|
|
||||||
|
All other files which have no copyright comments are original works
|
||||||
|
produced specifically for use as part of this library, written either
|
||||||
|
by Rich Felker, the main author of the library, or by one or more
|
||||||
|
contibutors listed above. Details on authorship of individual files
|
||||||
|
can be found in the git version control history of the project. The
|
||||||
|
omission of copyright and license comments in each file is in the
|
||||||
|
interest of source tree size.
|
||||||
|
|
||||||
|
In addition, permission is hereby granted for all public header files
|
||||||
|
(include/* and arch/*/bits/*) and crt files intended to be linked into
|
||||||
|
applications (crt/*, ldso/dlstart.c, and arch/*/crt_arch.h) to omit
|
||||||
|
the copyright notice and permission notice otherwise required by the
|
||||||
|
license, and to use these files without any requirement of
|
||||||
|
attribution. These files include substantial contributions from:
|
||||||
|
|
||||||
|
Bobby Bingham
|
||||||
|
John Spencer
|
||||||
|
Nicholas J. Kain
|
||||||
|
Rich Felker
|
||||||
|
Richard Pennington
|
||||||
|
Stefan Kristiansson
|
||||||
|
Szabolcs Nagy
|
||||||
|
|
||||||
|
all of whom have explicitly granted such permission.
|
||||||
|
|
||||||
|
This file previously contained text expressing a belief that most of
|
||||||
|
the files covered by the above exception were sufficiently trivial not
|
||||||
|
to be subject to copyright, resulting in confusion over whether it
|
||||||
|
negated the permissions granted in the license. In the spirit of
|
||||||
|
permissive licensing, and of not having licensing issues being an
|
||||||
|
obstacle to adoption, that text has been removed.
|
||||||
25
musl/memcpy.s
Normal file
25
musl/memcpy.s
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
.global memcpy
|
||||||
|
.global __memcpy_fwd
|
||||||
|
.hidden __memcpy_fwd
|
||||||
|
.type memcpy,@function
|
||||||
|
memcpy:
|
||||||
|
__memcpy_fwd:
|
||||||
|
mov %rdi,%rax
|
||||||
|
cmp $8,%rdx
|
||||||
|
jc 1f
|
||||||
|
test $7,%edi
|
||||||
|
jz 1f
|
||||||
|
2: movsb
|
||||||
|
dec %rdx
|
||||||
|
test $7,%edi
|
||||||
|
jnz 2b
|
||||||
|
1: mov %rdx,%rcx
|
||||||
|
shr $3,%rcx
|
||||||
|
rep
|
||||||
|
movsq
|
||||||
|
and $7,%edx
|
||||||
|
jz 1f
|
||||||
|
2: movsb
|
||||||
|
dec %edx
|
||||||
|
jnz 2b
|
||||||
|
1: ret
|
||||||
72
musl/memset.s
Normal file
72
musl/memset.s
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
.global memset
|
||||||
|
.type memset,@function
|
||||||
|
memset:
|
||||||
|
movzbq %sil,%rax
|
||||||
|
mov $0x101010101010101,%r8
|
||||||
|
imul %r8,%rax
|
||||||
|
|
||||||
|
cmp $126,%rdx
|
||||||
|
ja 2f
|
||||||
|
|
||||||
|
test %edx,%edx
|
||||||
|
jz 1f
|
||||||
|
|
||||||
|
mov %sil,(%rdi)
|
||||||
|
mov %sil,-1(%rdi,%rdx)
|
||||||
|
cmp $2,%edx
|
||||||
|
jbe 1f
|
||||||
|
|
||||||
|
mov %ax,1(%rdi)
|
||||||
|
mov %ax,(-1-2)(%rdi,%rdx)
|
||||||
|
cmp $6,%edx
|
||||||
|
jbe 1f
|
||||||
|
|
||||||
|
mov %eax,(1+2)(%rdi)
|
||||||
|
mov %eax,(-1-2-4)(%rdi,%rdx)
|
||||||
|
cmp $14,%edx
|
||||||
|
jbe 1f
|
||||||
|
|
||||||
|
mov %rax,(1+2+4)(%rdi)
|
||||||
|
mov %rax,(-1-2-4-8)(%rdi,%rdx)
|
||||||
|
cmp $30,%edx
|
||||||
|
jbe 1f
|
||||||
|
|
||||||
|
mov %rax,(1+2+4+8)(%rdi)
|
||||||
|
mov %rax,(1+2+4+8+8)(%rdi)
|
||||||
|
mov %rax,(-1-2-4-8-16)(%rdi,%rdx)
|
||||||
|
mov %rax,(-1-2-4-8-8)(%rdi,%rdx)
|
||||||
|
cmp $62,%edx
|
||||||
|
jbe 1f
|
||||||
|
|
||||||
|
mov %rax,(1+2+4+8+16)(%rdi)
|
||||||
|
mov %rax,(1+2+4+8+16+8)(%rdi)
|
||||||
|
mov %rax,(1+2+4+8+16+16)(%rdi)
|
||||||
|
mov %rax,(1+2+4+8+16+24)(%rdi)
|
||||||
|
mov %rax,(-1-2-4-8-16-32)(%rdi,%rdx)
|
||||||
|
mov %rax,(-1-2-4-8-16-24)(%rdi,%rdx)
|
||||||
|
mov %rax,(-1-2-4-8-16-16)(%rdi,%rdx)
|
||||||
|
mov %rax,(-1-2-4-8-16-8)(%rdi,%rdx)
|
||||||
|
|
||||||
|
1: mov %rdi,%rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
2: test $15,%edi
|
||||||
|
mov %rdi,%r8
|
||||||
|
mov %rax,-8(%rdi,%rdx)
|
||||||
|
mov %rdx,%rcx
|
||||||
|
jnz 2f
|
||||||
|
|
||||||
|
1: shr $3,%rcx
|
||||||
|
rep
|
||||||
|
stosq
|
||||||
|
mov %r8,%rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
2: xor %edx,%edx
|
||||||
|
sub %edi,%edx
|
||||||
|
and $15,%edx
|
||||||
|
mov %rax,(%rdi)
|
||||||
|
mov %rax,8(%rdi)
|
||||||
|
sub %rdx,%rcx
|
||||||
|
add %rdx,%rdi
|
||||||
|
jmp 1b
|
||||||
Reference in New Issue
Block a user