130 lines
3.6 KiB
Plaintext
130 lines
3.6 KiB
Plaintext
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";
|