102 lines
2.6 KiB
Odin
102 lines
2.6 KiB
Odin
package d2;
|
|
|
|
import "core:os"
|
|
import "core:fmt"
|
|
|
|
die :: proc (eno: os.Errno) {
|
|
fmt.printf("Fatal error: %s\n", os.get_last_error_string());
|
|
os.exit(int(eno));
|
|
}
|
|
|
|
usage :: proc() {
|
|
fmt.printf("Usage: ./%s FILENAME\n", os.args[0]);
|
|
}
|
|
|
|
BUFFER_SIZE :: 1024;
|
|
State :: enum {
|
|
NONE, READ_ID, READ_RESULT, READ_DELIM, READ_COLON, READ_NEWLINE
|
|
}
|
|
Result :: struct{
|
|
red: int, green: int, blue: int,
|
|
};
|
|
TARGET_GAME :: Result{12, 13, 14};
|
|
games: [dynamic]Result = make([dynamic]Result);
|
|
stack: [dynamic]State = make([dynamic]State);
|
|
|
|
collect_digits :: proc(buffer: []u8, index: ^int) -> int {
|
|
assert(index^ < len(buffer));
|
|
result := 0
|
|
for '0' <= buffer[index^] && buffer[index^] <= '9' && index^ < len(buffer) {
|
|
result *= 10;
|
|
result += int(buffer[index^] - '0');
|
|
index^ += 1;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
consume_token :: proc(token: string, buffer: []u8, index: ^int) -> bool {
|
|
bi := index^;
|
|
ti := 0;
|
|
for ti < len(token) {
|
|
if bi >= len(buffer) || buffer[bi] != token[ti] {
|
|
return false;
|
|
} else {
|
|
ti += 1; bi += 1;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
attempt_1 :: proc() {
|
|
if len(os.args) < 2 {
|
|
usage();
|
|
os.exit(-1);
|
|
}
|
|
fh, eno := os.open(os.args[1], os.O_RDONLY);
|
|
if eno != os.ERROR_NONE { die(eno); }
|
|
defer os.close(fh);
|
|
id := -1;
|
|
red, green, blue, num_read: int;
|
|
state := State.READ_ID;
|
|
total := 0;
|
|
buffer, ok := os.read_entire_file_from_handle(fh);
|
|
if !ok {
|
|
// die(os.get_last_error());
|
|
// TODO
|
|
os.exit(-1);
|
|
}
|
|
ix := 0;
|
|
for ix < len(buffer) {
|
|
if eno != os.ERROR_NONE { die(eno); }
|
|
switch pop(&stack) {
|
|
case .READ_ID:
|
|
id = collect_digits(buffer, &ix);
|
|
append(&stack, State.READ_RESULT);
|
|
append(&stack, State.READ_DELIM);
|
|
append(&stack, State.READ_COLON);
|
|
case .READ_COLON:
|
|
if !consume_token(":", buffer, &ix) {
|
|
// TODO
|
|
os.exit(-1);
|
|
}
|
|
case .READ_DELIM:
|
|
for ix < len(buffer) && buffer[ix] == ' ' {
|
|
ix += 1;
|
|
}
|
|
case .READ_NEWLINE:
|
|
if !consume_token("\n", buffer, &ix) {
|
|
// TODO
|
|
os.exit(-1);
|
|
}
|
|
case .READ_RESULT:
|
|
append(&stack, State.READ_ID);
|
|
append(&stack, State.READ_NEWLINE);
|
|
case .NONE:
|
|
os.exit(-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
main :: proc() {
|
|
attempt_1();
|
|
} |