sample :: #string END ..@@.@@@@. @@@.@.@.@@ @@@@@.@.@@ @.@@@@..@. @@.@@@@.@@ .@@@@@@@.@ .@.@.@.@@@ @.@@@.@@@@ .@@@@@@@@. @.@.@@@.@. END main :: () { print("@: %\n", #char "@"); print(".: %\n", #char "."); content := read_entire_file("day4.input"); solve_first(content); solve_second(content); } solve_first :: (input: string) { all_lines := split(input, #char "\n"); lines: [..]string; for line: all_lines { if line.count == 0 continue; array_add(*lines, line); } assert(lines[0].count != 0); line_length := lines[0].count; removable := 0; for line, line_index: lines { if line.count == 0 continue; for char, char_index: line { if char == #char "." continue; surrounding_chars: [8]u8; surrounding_chars_index := 0; for dy: -1..1 { for dx: -1..1 { if dx == 0 && dy == 0 continue; defer surrounding_chars_index += 1; x := char_index + dx; if x < 0 || line.count <= x continue; y := line_index + dy; if y < 0 || lines.count <= y continue; surrounding_chars[surrounding_chars_index] = lines[y][x]; } } if array_count(surrounding_chars, (char: u8) -> bool { return char == #char "@"; }) < 4 { removable += 1; } } } print("%\n", removable); } Point :: struct { line_index: int; char_index: int; } solve_second :: (input: string) { all_lines := split(input, #char "\n"); lines: [..][..]u8; array_reserve(*lines, all_lines.count); for line: all_lines { if line.count == 0 continue; chars: [..]u8; array_reserve(*chars, line.count); for line { array_add(*chars, it); } array_add(*lines, chars); } assert(lines[0].count != 0); line_length := lines[0].count; removed := 0; any_removed := true; while any_removed { any_removed = false; points_to_remove: [..]Point; points_to_remove.allocator = temp; array_reserve(*points_to_remove, line_length); defer reset_temporary_storage(); for line, line_index: lines { if line.count == 0 continue; for char, char_index: line { if char == #char "." continue; surrounding_chars: [8]u8; surrounding_chars_index := 0; for dy: -1..1 { for dx: -1..1 { if dx == 0 && dy == 0 continue; defer surrounding_chars_index += 1; x := char_index + dx; if x < 0 || line.count <= x continue; y := line_index + dy; if y < 0 || lines.count <= y continue; surrounding_chars[surrounding_chars_index] = lines[y][x]; } } if array_count(surrounding_chars, (char: u8) -> bool { return char == #char "@"; }) < 4 { removed += 1; any_removed = true; array_add(*points_to_remove, .{line_index=line_index, char_index=char_index}); } } } for points_to_remove { lines[it.line_index][it.char_index] = #char "."; } } print("%\n", removed); } array_count :: (arr: []$T, f: (t: T) -> bool) -> int { total := 0; for arr { if f(it) total += 1; } return total; } #import "Basic"; #import "File"; #import "String";