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