Files
advent-of-code-2023/d2/main.odin
2024-11-14 19:16:08 -05:00

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();
}