161 lines
4.5 KiB
Odin
161 lines
4.5 KiB
Odin
package day01
|
|
|
|
import "core:fmt"
|
|
import "core:os"
|
|
import "core:math"
|
|
import "core:strconv"
|
|
import "core:slice/heap"
|
|
|
|
scan_to_next :: proc(data: []byte, delim: byte, start_from: int) -> int {
|
|
for idx := start_from; idx < len(data); idx += 1 {
|
|
if data[idx] == '\n' {
|
|
return idx
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
main_first_attempt :: proc () {
|
|
// Read in input file.
|
|
fh, errno := os.open("day01/calories-basic.input")
|
|
if errno != os.ERROR_NONE {
|
|
panic("Don't know what to do!")
|
|
}
|
|
defer os.close(fh)
|
|
|
|
line_start := 0
|
|
line_end := -1
|
|
repr := 0
|
|
sum := 0
|
|
max := -1
|
|
content: []byte
|
|
ok: bool
|
|
content, ok = os.read_entire_file_from_handle(fh)
|
|
if !ok { return; }
|
|
|
|
for line_start < len(content) {
|
|
|
|
if content[line_start] == '\n' {
|
|
fmt.println(line_start, " starts a blank line: skipping to ", line_start + 1)
|
|
// Case: line is blank
|
|
// End summation; we are in a new group
|
|
max = math.max(max, sum)
|
|
|
|
// OK YOU NEED TO BE VERY CAREFUL WITH THIS! FIRST ODIN FOOTGUN!
|
|
// This line used to be `sum := 0` instead of `sum = 0` and I
|
|
// think that re-defined `sum` in this local scope because the
|
|
// total sum at the end was way too high; it never got reset to 0
|
|
// here. If you think about it, it makes sense... but I would think
|
|
// the compiler might warn me that I was shadowing something from
|
|
// ouside the scope...
|
|
sum = 0
|
|
|
|
// Go to next line
|
|
line_start += 1
|
|
continue
|
|
}
|
|
|
|
line_end = scan_to_next(content, '\n', line_start + 1)
|
|
fmt.println("Next line: ", line_start, " thru ", line_end)
|
|
|
|
// Case: no newlines left
|
|
if line_end == -1 {
|
|
// Get last line
|
|
slc := string(content[line_start:len(content)])
|
|
repr, ok = strconv.parse_int(slc)
|
|
if !ok {
|
|
// Line doesn't have a number on it?
|
|
// TODO Just ignore for now
|
|
} else {
|
|
fmt.println("Result: ", repr, " Current Sum: ", sum + repr)
|
|
sum += repr
|
|
max = math.max(max, sum)
|
|
sum = 0
|
|
}
|
|
break
|
|
}
|
|
|
|
// Case: Normal line with a number on it
|
|
slc := string(content[line_start:line_end])
|
|
fmt.println("Reading line: ", slc)
|
|
repr, ok = strconv.parse_int(slc)
|
|
if !ok {
|
|
// Line doesn't have a number on it?
|
|
// TODO Just ignore for now
|
|
} else {
|
|
fmt.println("Result: ", repr, " Current Sum: ", sum + repr)
|
|
sum += repr
|
|
}
|
|
line_start = line_end + 1
|
|
}
|
|
fmt.println("Largest group is ", max);
|
|
}
|
|
|
|
split_lines :: proc(data: []byte, delimiter: byte) -> [dynamic][]byte {
|
|
result: [dynamic][]byte
|
|
prev := 0
|
|
idx: int
|
|
for idx = 0; idx < len(data); idx += 1 {
|
|
if data[idx] == delimiter {
|
|
append(&result, data[prev:idx])
|
|
prev = idx + 1
|
|
}
|
|
}
|
|
if prev < idx {
|
|
append(&result, data[prev:idx])
|
|
}
|
|
return result
|
|
}
|
|
|
|
main :: proc() {
|
|
if len(os.args) < 2 {
|
|
fmt.printf("Usage: %s FILENAME\n", os.args[0])
|
|
os.exit(-1)
|
|
}
|
|
fh, errno := os.open(os.args[1])
|
|
if errno != os.ERROR_NONE {
|
|
fmt.printf("Cannot open %s: %s\n", os.args[1], os.get_last_error_string())
|
|
os.exit(-1)
|
|
}
|
|
defer os.close(fh)
|
|
content, ok := os.read_entire_file_from_handle(fh)
|
|
if !ok {
|
|
fmt.printf("Cannot read %s: %s\n", os.args[1], os.get_last_error_string())
|
|
os.exit(-1)
|
|
}
|
|
lines := split_lines(content, '\n')
|
|
total := 0
|
|
mh := make([dynamic]int, context.temp_allocator)
|
|
defer delete(mh)
|
|
comparator :: proc(a, b: int) -> bool {
|
|
return a < b
|
|
}
|
|
heap.make(mh[:], comparator)
|
|
|
|
for line, idx in lines {
|
|
if len(line) == 0 {
|
|
append(&mh, total)
|
|
heap.push(mh[:], comparator)
|
|
total = 0
|
|
} else {
|
|
x: int
|
|
s := string(line)
|
|
x, ok = strconv.parse_int(s)
|
|
if ok {
|
|
total += x
|
|
} else {
|
|
fmt.eprintf("Line %d: not a valid integer\n", idx)
|
|
}
|
|
}
|
|
}
|
|
append(&mh, total)
|
|
heap.make(mh[:], comparator)
|
|
total = 0
|
|
fmt.printf("Largest single value: %d\n", mh[0])
|
|
for _ in 0..<3 {
|
|
total += mh[0]
|
|
heap.pop(mh[:], comparator)
|
|
}
|
|
fmt.printf("Sum of three largest: %d\n", total)
|
|
}
|