package main import "core:log" import "core:os" import "core:slice" import "core:strings" Input :: struct { grid: [][]u8, } Result1 :: distinct int Result2 :: distinct int // --- Input --- // print_input :: proc(input: ^Input) { for line in input.grid { log.infof("%s", line) } } 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 := strings.split_lines(string(raw_data)) defer delete(lines) input.grid = make([][]u8, len(lines) - 1) i: int for line in lines { if len(line) == 0 { continue } input.grid[i] = slice.clone(transmute([]u8)line[:]) i += 1 } return input } free_input :: proc(input: ^Input) { for _, i in input.grid { delete(input.grid[i]) } delete(input.grid) } // --- Input --- // // --- Helpers --- // Direction :: enum { Up, Down, Left, Right, UpLeft, UpRight, DownLeft, DownRight, } print_grid :: proc(grid: [][]u8) { for line in grid { log.debugf("%s", line) } } // --- Helpers --- // // --- Task 1 --- // run_task1 :: proc(input: ^Input, debug: bool) -> Result1 { result: Result1 if debug { print_input(input) } grid := make([][]u8, len(input.grid)) for _, i in grid { grid[i] = make([]u8, len(input.grid[i])) } defer { for _, i in grid { delete(grid[i]) } delete(grid) } chars := []u8{'X', 'M', 'A', 'S'} height := len(grid) for y in 0 ..< height { width := len(grid[y]) for x in 0 ..< width { if input.grid[y][x] != 'X' { grid[y][x] = '.' continue } matches: [Direction]int for c, i in chars { if y - i >= 0 { if c == input.grid[y - i][x] { matches[.Up] += 1 } } if y + i < height { if c == input.grid[y + i][x] { matches[.Down] += 1 } } if x - i >= 0 { if c == input.grid[y][x - i] { matches[.Left] += 1 } } if x + i < width { if c == input.grid[y][x + i] { matches[.Right] += 1 } } if y - i >= 0 && x - i >= 0 { if c == input.grid[y - i][x - i] { matches[.UpLeft] += 1 } } if y - i >= 0 && x + i < width { if c == input.grid[y - i][x + i] { matches[.UpRight] += 1 } } if y + i < height && x - i >= 0 { if c == input.grid[y + i][x - i] { matches[.DownLeft] += 1 } } if y + i < height && x + i < width { if c == input.grid[y + i][x + i] { matches[.DownRight] += 1 } } } log.debugf("%v", matches) grid[y][x] = 'F' for m in matches { if m == len(chars) { grid[y][x] = 'T' result += 1 } } } } print_grid(grid) return result } print_result1 :: proc(result: ^Result1) { log.infof("Task 1: %d", result^) } // --- Task 1 --- // // --- Task 2 --- // run_task2 :: proc(input: ^Input, debug: bool) -> Result2 { result: Result2 if debug { print_input(input) } grid := make([][]u8, len(input.grid)) for _, i in grid { grid[i] = make([]u8, len(input.grid[i])) } defer { for _, i in grid { delete(grid[i]) } delete(grid) } height := len(grid) for y in 1 ..< height - 1 { width := len(grid[y]) for x in 1 ..< width - 1 { if input.grid[y][x] != 'A' { grid[y][x] = ' ' continue } matches: int if 'M' == input.grid[y - 1][x - 1] && 'S' == input.grid[y + 1][x + 1] { matches += 1 } if 'S' == input.grid[y - 1][x - 1] && 'M' == input.grid[y + 1][x + 1] { matches += 1 } if 'M' == input.grid[y + 1][x - 1] && 'S' == input.grid[y - 1][x + 1] { matches += 1 } if 'S' == input.grid[y + 1][x - 1] && 'M' == input.grid[y - 1][x + 1] { matches += 1 } grid[y][x] = 'T' if matches == 2 else 'F' if matches == 2 { result += 1 } } } print_grid(grid) return result } print_result2 :: proc(result: ^Result2) { log.infof("Task 2: %d", result^) } // --- Task 2 --- //