package day_04
import "core:log"
import "core:os"
import "core:slice"
import "core:strings"
Input :: struct {
width: int,
grid: []u8,
}
Result1 :: int
Result2 :: int
// --- Input --- //
print_input :: proc(input: Input) {
offset := 0
for _ in 0 ..< input.width {
log.infof("%v", string(input.grid[offset:offset + input.width]))
offset += input.width
}
}
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, err := strings.split_lines(strings.trim_right_space(string(raw_data)))
if err != .None {
panic("oh no, failed splitting into lines")
}
defer delete(lines)
input.width = len(lines[0])
input.grid = make([]u8, input.width * input.width)
offset := 0
for line in lines {
for c in line {
input.grid[offset] = u8(c)
offset += 1
}
}
return input
}
free_input :: proc(input: ^Input) {
delete(input.grid)
input.grid = nil
}
// --- Input --- //
// --- Helpers --- //
print_grid :: proc(grid: []u8, width: int) {
offset := 0
for _ in 0 ..< width {
log.debugf("%v", string(grid[offset:offset + width]))
offset += width
}
}
// --- Helpers --- //
// --- Task 1 --- //
run_task1 :: proc(input: Input) -> Result1 {
result: Result1
ymin, ymax := 0, input.width - 1
xmin, xmax := 0, input.width - 1
i := 0
for y in 0 ..< input.width {
for x in 0 ..< input.width {
if input.grid[i] == '@' {
c: int
if y > ymin {
c += 1 if x > xmin && input.grid[i - input.width - 1] == '@' else 0
c += 1 if input.grid[i - input.width] == '@' else 0
c += 1 if x < xmax && input.grid[i - input.width + 1] == '@' else 0
}
c += 1 if x > xmin && input.grid[i - 1] == '@' else 0
c += 1 if x < xmax && input.grid[i + 1] == '@' else 0
if y < ymax {
c += 1 if x > xmin && input.grid[i + input.width - 1] == '@' else 0
c += 1 if input.grid[i + input.width] == '@' else 0
c += 1 if x < xmax && input.grid[i + input.width + 1] == '@' else 0
}
if c < 4 {
result += 1
}
}
i += 1
}
}
return result
}
print_result1 :: proc(result: Result1) {
log.infof("Task 1: %d", result)
}
// --- Task 1 --- //
// --- Task 2 --- //
run_task2 :: proc(input: Input) -> Result2 {
result: Result2
ymin, ymax := 0, input.width - 1
xmin, xmax := 0, input.width - 1
grid_a := slice.clone(input.grid)
defer delete(grid_a)
grid_b := slice.clone(input.grid)
defer delete(grid_b)
keep_running := true
for keep_running {
keep_running = false
i := 0
for y in 0 ..< input.width {
for x in 0 ..< input.width {
if grid_a[i] == '@' {
c: int
if y > ymin {
c += 1 if x > xmin && grid_a[i - input.width - 1] == '@' else 0
c += 1 if grid_a[i - input.width] == '@' else 0
c += 1 if x < xmax && grid_a[i - input.width + 1] == '@' else 0
}
c += 1 if x > xmin && grid_a[i - 1] == '@' else 0
c += 1 if x < xmax && grid_a[i + 1] == '@' else 0
if y < ymax {
c += 1 if x > xmin && grid_a[i + input.width - 1] == '@' else 0
c += 1 if grid_a[i + input.width] == '@' else 0
c += 1 if x < xmax && grid_a[i + input.width + 1] == '@' else 0
}
if c < 4 {
result += 1
grid_b[i] = 'x'
keep_running = true
} else {
grid_b[i] = grid_a[i]
}
} else {
grid_b[i] = grid_a[i]
}
i += 1
}
}
grid_a, grid_b = grid_b, grid_a
print_grid(grid_a, input.width)
log.debugf("---")
}
return result
}
print_result2 :: proc(result: Result2) {
log.infof("Task 2: %d", result)
}
// --- Task 2 --- //
run :: proc() {
input := parse_input_file("input/day_04.txt")
defer free_input(&input)
result1 := run_task1(input)
print_result1(result1)
result2 := run_task2(input)
print_result2(result2)
}