package day_04 import "core:log" import "core:os" import "core:slice" import "core:strings" Input :: struct { width: int, grid: []u8, } Result1 :: int Result2 :: int // --- Input --- // print_input :: proc(input: Input) { offset := 0 for _ in 0 ..< input.width { log.infof("%v", string(input.grid[offset:offset + input.width])) offset += input.width } } 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) input.width = len(lines[0]) input.grid = make([]u8, input.width * input.width) offset := 0 for line in lines { for c in line { input.grid[offset] = u8(c) offset += 1 } } return input } free_input :: proc(input: ^Input) { delete(input.grid) input.grid = nil } // --- Input --- // // --- Helpers --- // print_grid :: proc(grid: []u8, width: int) { offset := 0 for _ in 0 ..< width { log.debugf("%v", string(grid[offset:offset + width])) offset += width } } // --- Helpers --- // // --- Task 1 --- // run_task1 :: proc(input: Input) -> Result1 { result: Result1 ymin, ymax := 0, input.width - 1 xmin, xmax := 0, input.width - 1 i := 0 for y in 0 ..< input.width { for x in 0 ..< input.width { if input.grid[i] == '@' { c: int if y > ymin { c += 1 if x > xmin && input.grid[i - input.width - 1] == '@' else 0 c += 1 if input.grid[i - input.width] == '@' else 0 c += 1 if x < xmax && input.grid[i - input.width + 1] == '@' else 0 } c += 1 if x > xmin && input.grid[i - 1] == '@' else 0 c += 1 if x < xmax && input.grid[i + 1] == '@' else 0 if y < ymax { c += 1 if x > xmin && input.grid[i + input.width - 1] == '@' else 0 c += 1 if input.grid[i + input.width] == '@' else 0 c += 1 if x < xmax && input.grid[i + input.width + 1] == '@' else 0 } if c < 4 { result += 1 } } i += 1 } } 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 ymin, ymax := 0, input.width - 1 xmin, xmax := 0, input.width - 1 grid_a := slice.clone(input.grid) defer delete(grid_a) grid_b := slice.clone(input.grid) defer delete(grid_b) keep_running := true for keep_running { keep_running = false i := 0 for y in 0 ..< input.width { for x in 0 ..< input.width { if grid_a[i] == '@' { c: int if y > ymin { c += 1 if x > xmin && grid_a[i - input.width - 1] == '@' else 0 c += 1 if grid_a[i - input.width] == '@' else 0 c += 1 if x < xmax && grid_a[i - input.width + 1] == '@' else 0 } c += 1 if x > xmin && grid_a[i - 1] == '@' else 0 c += 1 if x < xmax && grid_a[i + 1] == '@' else 0 if y < ymax { c += 1 if x > xmin && grid_a[i + input.width - 1] == '@' else 0 c += 1 if grid_a[i + input.width] == '@' else 0 c += 1 if x < xmax && grid_a[i + input.width + 1] == '@' else 0 } if c < 4 { result += 1 grid_b[i] = 'x' keep_running = true } else { grid_b[i] = grid_a[i] } } else { grid_b[i] = grid_a[i] } i += 1 } } grid_a, grid_b = grid_b, grid_a print_grid(grid_a, input.width) log.debugf("---") } return result } print_result2 :: proc(result: Result2) { log.infof("Task 2: %d", result) } // --- Task 2 --- // run :: proc() { input := parse_input_file("input/day_04.txt") defer free_input(&input) result1 := run_task1(input) print_result1(result1) result2 := run_task2(input) print_result2(result2) }