package day_07 import "core:fmt" import "core:log" import "core:os" import "core:strings" Input :: struct { starts_at: [2]int, width, height: int, splitters: map[[2]int]bool, } 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_space(string(raw_data))) if err != .None { panic("oh no, failed splitting into lines") } defer delete(lines) input.width = len(lines[0]) input.height = len(lines) input.splitters = make(map[[2]int]bool) for line, y in lines { for c, x in line { if c == 'S' { input.starts_at = {x, y} } else if c == '^' { input.splitters[{x, y}] = true } } } return input } free_input :: proc(input: ^Input) { delete(input.splitters) } // --- Input --- // // --- Helpers --- // print_tree :: proc(input: Input) { b: strings.Builder strings.builder_init(&b) defer strings.builder_destroy(&b) fmt.sbprint(&b, "\n") for y in 0 ..< input.height { for x in 0 ..< input.width { if input.starts_at == {x, y} { fmt.sbprint(&b, "S") } else if ({x, y}) in input.splitters { fmt.sbprint(&b, "^") } else { fmt.sbprint(&b, ".") } } fmt.sbprint(&b, "\n") } log.infof(strings.to_string(b)) } process_beam := proc(input: Input) -> (hit_splitters, num_timelines: int) { grid := make([]int, input.width * input.height) defer delete(grid) grid[(input.starts_at.y * input.width) + input.starts_at.x] = 1 for y in 1 ..< input.height { i := y * input.width for x in 0 ..< input.width { pos := [2]int{x, y} timeline := grid[i + x - input.width] if timeline > 0 { if pos in input.splitters { hit_splitters += 1 grid[i + x - 1] += timeline grid[i + x + 1] += timeline } else { grid[i + x] += timeline } } } } for i in len(grid) - input.width ..< len(grid) { num_timelines += grid[i] } print_grid(grid, input.width, input.height) return hit_splitters, num_timelines } print_grid :: proc(grid: []int, width, height: int) { b: strings.Builder strings.builder_init(&b) defer strings.builder_destroy(&b) fmt.sbprint(&b, "\n") for y in 0 ..< height { i := y * width for x in 0 ..< width { c := grid[i + x] if c > 0 { fmt.sbprintf(&b, " %d ", c) } else { fmt.sbprint(&b, " . ") } } fmt.sbprint(&b, "\n") } log.debugf(strings.to_string(b)) } // --- Helpers --- // // --- Task 1 --- // run_task1 :: proc(input: Input) -> Result1 { result: Result1 hit_splitters, _ := process_beam(input) result += hit_splitters 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 _, num_timelines := process_beam(input) result += num_timelines return result } print_result2 :: proc(result: Result2) { log.infof("Task 2: %d", result) } // --- Task 2 --- // run :: proc() { input := parse_input_file("input/day_07.txt") defer free_input(&input) result1 := run_task1(input) print_result1(result1) result2 := run_task2(input) print_result2(result2) }