package main import "core:container/queue" import "core:fmt" import "core:math" import "core:os" import "core:slice" import "core:strconv" import "core:strings" import "core:time" import "core:unicode/utf8" import util "../util" Vec2 :: [2]int in_bounds :: proc(pos: Vec2, lines: ^[][]u8) -> bool { return pos.x >= 0 && pos.x < len(lines[0]) && pos.y >= 0 && pos.y < len(lines) } part_1 :: proc(lines: ^[][]u8) { result: i64 = 0 directions := [8]Vec2{{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}} for line, y in lines { for ch, x in line { if ch != '@' do continue adj_paperroll := 0 pos := Vec2{x, y} for dir in directions { adj_pos := pos + dir if in_bounds(adj_pos, lines) { adj_ch := lines[adj_pos.y][adj_pos.x] if adj_ch == '@' do adj_paperroll += 1 } } if adj_paperroll < 4 do result += 1 } } fmt.printfln(" [Result] %v", result) } count_rolls :: proc(lines: ^[][]u8) -> (acc: int) { for line in lines { for ch in line do if ch == '@' do acc += 1 } return } part_2 :: proc(lines: ^[][]u8) { result := 0 directions := [8]Vec2{{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}} to_remove := make([dynamic]Vec2) mutable_lines := make([][]u8, len(lines)) for line, i in lines { mutable_lines[i] = slice.clone(line) } rolls := count_rolls(&mutable_lines) for true { for line, y in mutable_lines { for ch, x in line { if ch != '@' do continue adj_paperroll := 0 pos := Vec2{x, y} for dir in directions { adj_pos := pos + dir if in_bounds(adj_pos, &mutable_lines) { adj_ch := mutable_lines[adj_pos.y][adj_pos.x] if adj_ch == '@' do adj_paperroll += 1 } } if adj_paperroll < 4 do append(&to_remove, pos) } } for pos in to_remove do mutable_lines[pos.y][pos.x] = '.' result += len(to_remove) clear(&to_remove) new_rolls := count_rolls(&mutable_lines) if new_rolls == rolls do break else do rolls = new_rolls } fmt.printfln(" [Result] %v", result) } main :: proc() { context.allocator = context.temp_allocator defer free_all(context.temp_allocator) INPUT :: #load("input.txt") lines := strings.split_lines(string(INPUT)) lines = lines[:len(lines) - 1] byte_lines := make([][]u8, len(lines)) for line, i in lines do byte_lines[i] = transmute([]u8)line fmt.println("[Part 1]") start := time.tick_now() part_1(&byte_lines) duration := time.tick_diff(start, time.tick_now()) fmt.printfln(" [Time] %fms\n", time.duration_milliseconds(duration)) fmt.printfln("[Part 2]") start = time.tick_now() part_2(&byte_lines) duration = time.tick_diff(start, time.tick_now()) fmt.printfln(" [Time] %fms", time.duration_milliseconds(duration)) }