package main import "core:fmt" import "core:os" parse_input_file :: proc(filepath: string, buffer: []int) -> (stride: int, sliced: []int) { data, ok := os.read_entire_file_from_filename(filepath) if !ok { panic("oh no, could not read file") } index: int for b, i in data { if b == '\n' { stride = i if stride == 0 else stride continue } buffer[index] = cast(int)(b - 48) index += 1 } sliced = buffer[:index] return } Vec2 :: [2]int check_visible :: proc(start: Vec2, dir: Vec2, stride: int, heights: []int) -> (bool, int) { max := heights[(start[1] * stride) + start[0]] current := start + dir steps: int for { if current[0] < 0 || current[0] >= stride { return true, steps } if current[1] < 0 || current[1] >= stride { return true, steps } i := (current[1] * stride) + current[0] if heights[i] >= max { return false, steps + 1 } current += dir steps += 1 } panic("unreachable!") } task1 :: proc(stride: int, heights: []int) -> int { result: int for y in 0 ..< stride { for x in 0 ..< stride { pos := Vec2{x, y} dirs := []Vec2{{0, -1}, {-1, 0}, {1, 0}, {0, 1}} visible: bool for d in dirs { if found_edge, _ := check_visible(pos, d, stride, heights); found_edge { visible = true break } } if visible { result += 1 } } } return result } task2 :: proc(stride: int, heights: []int) -> int { result: int for y in 0 ..< stride { for x in 0 ..< stride { pos := Vec2{x, y} dirs := []Vec2{{0, -1}, {-1, 0}, {1, 0}, {0, 1}} score := 1 for d in dirs { _, distance := check_visible(pos, d, stride, heights) score *= distance } result = score if score > result else result } } return result } main :: proc() { buffer: [65353]int stride, heights := parse_input_file("input.txt", buffer[:]) result1 := task1(stride, heights) fmt.printf("Task 1 result: %d\n", result1) result2 := task2(stride, heights) fmt.printf("Task 2 result: %d\n", result2) }