package day_05 import "core:log" import "core:os" import "core:strconv" import "core:strings" Input :: struct { fresh_ranges: [][2]int, ingredients: []int, } Result1 :: int Result2 :: int // --- Input --- // print_input :: proc(input: Input) { log.infof("%#v", input) } parse_input_file :: proc(filepath: string) -> Input { input: Input raw_data, ok := os.read_entire_file_from_filename(filepath) if !ok { panic("oh no, could not read file") } defer delete(raw_data) lines, err := strings.split_lines(strings.trim_right_space(string(raw_data))) if err != .None { panic("oh no, failed splitting into lines") } defer delete(lines) split := 0 for line, i in lines { if line == "" { split = i break } } input.fresh_ranges = make([][2]int, split) input.ingredients = make([]int, len(lines) - split - 1) for line, i in lines[:split] { range := strings.split(line, "-") defer delete(range) a := strconv.parse_int(range[0]) or_else 0 b := strconv.parse_int(range[1]) or_else 0 input.fresh_ranges[i] = {a, b} } for line, i in lines[split + 1:] { input.ingredients[i] = strconv.parse_int(line) or_else 0 } log.debugf("%d %d", len(input.ingredients), len(input.fresh_ranges)) log.debugf("%#v", input) return input } free_input :: proc(input: ^Input) { delete(input.fresh_ranges) delete(input.ingredients) } // --- Input --- // // --- Helpers --- // // --- Helpers --- // // --- Task 1 --- // run_task1 :: proc(input: Input) -> Result1 { result: Result1 for i in input.ingredients { for fr in input.fresh_ranges { if i >= fr[0] && i <= fr[1] { result += 1 break } } } return result } print_result1 :: proc(result: Result1) { log.infof("Task 1: %d", result) } // --- Task 1 --- // // --- Task 2 --- // run_task2 :: proc(input: Input) -> Result2 { result: Result2 ranges := input.fresh_ranges current_ranges := make([][2]int, len(ranges)) defer delete(current_ranges) expanded := true for expanded { expanded = false for i := 0; i < len(ranges); i += 1 { current := ranges[i] if current == {0, 0} { continue } for j := i + 1; j < len(ranges); j += 1 { range := ranges[j] if range == {0, 0} { continue } if current[0] <= range[1] && range[0] <= current[1] { current[0] = min(current[0], range[0]) current[1] = max(current[1], range[1]) expanded = true ranges[j] = {0, 0} } } current_ranges[i] = current } ranges = current_ranges log.debugf("%v -> %v", ranges, current_ranges) } log.debugf("final ranges %#v", ranges) for r in ranges { if r == {0, 0} { continue } result += (r[1] - r[0]) + 1 } return result } print_result2 :: proc(result: Result2) { log.infof("Task 2: %d", result) } // --- Task 2 --- // run :: proc() { input := parse_input_file("input/day_05.txt") defer free_input(&input) result1 := run_task1(input) print_result1(result1) result2 := run_task2(input) print_result2(result2) }