package day_07
import "core:fmt"
import "core:log"
import "core:os"
import "core:strings"
Input :: struct {
starts_at: [2]int,
width, height: int,
splitters: map[[2]int]bool,
}
Result1 :: int
Result2 :: int
// --- Input --- //
print_input :: proc(input: Input) {
log.infof("%#v", input)
}
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_space(string(raw_data)))
if err != .None {
panic("oh no, failed splitting into lines")
}
defer delete(lines)
input.width = len(lines[0])
input.height = len(lines)
input.splitters = make(map[[2]int]bool)
for line, y in lines {
for c, x in line {
if c == 'S' {
input.starts_at = {x, y}
} else if c == '^' {
input.splitters[{x, y}] = true
}
}
}
return input
}
free_input :: proc(input: ^Input) {
delete(input.splitters)
}
// --- Input --- //
// --- Helpers --- //
print_tree :: proc(input: Input) {
b: strings.Builder
strings.builder_init(&b)
defer strings.builder_destroy(&b)
fmt.sbprint(&b, "\n")
for y in 0 ..< input.height {
for x in 0 ..< input.width {
if input.starts_at == {x, y} {
fmt.sbprint(&b, "S")
} else if ({x, y}) in input.splitters {
fmt.sbprint(&b, "^")
} else {
fmt.sbprint(&b, ".")
}
}
fmt.sbprint(&b, "\n")
}
log.infof(strings.to_string(b))
}
process_beam := proc(input: Input) -> (hit_splitters, num_timelines: int) {
grid := make([]int, input.width * input.height)
defer delete(grid)
grid[(input.starts_at.y * input.width) + input.starts_at.x] = 1
for y in 1 ..< input.height {
i := y * input.width
for x in 0 ..< input.width {
pos := [2]int{x, y}
timeline := grid[i + x - input.width]
if timeline > 0 {
if pos in input.splitters {
hit_splitters += 1
grid[i + x - 1] += timeline
grid[i + x + 1] += timeline
} else {
grid[i + x] += timeline
}
}
}
}
for i in len(grid) - input.width ..< len(grid) {
num_timelines += grid[i]
}
print_grid(grid, input.width, input.height)
return hit_splitters, num_timelines
}
print_grid :: proc(grid: []int, width, height: int) {
b: strings.Builder
strings.builder_init(&b)
defer strings.builder_destroy(&b)
fmt.sbprint(&b, "\n")
for y in 0 ..< height {
i := y * width
for x in 0 ..< width {
c := grid[i + x]
if c > 0 {
fmt.sbprintf(&b, " %d ", c)
} else {
fmt.sbprint(&b, " . ")
}
}
fmt.sbprint(&b, "\n")
}
log.debugf(strings.to_string(b))
}
// --- Helpers --- //
// --- Task 1 --- //
run_task1 :: proc(input: Input) -> Result1 {
result: Result1
hit_splitters, _ := process_beam(input)
result += hit_splitters
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
_, num_timelines := process_beam(input)
result += num_timelines
return result
}
print_result2 :: proc(result: Result2) {
log.infof("Task 2: %d", result)
}
// --- Task 2 --- //
run :: proc() {
input := parse_input_file("input/day_07.txt")
defer free_input(&input)
result1 := run_task1(input)
print_result1(result1)
result2 := run_task2(input)
print_result2(result2)
}