125 lines
2.5 KiB
Odin
125 lines
2.5 KiB
Odin
package day4
|
|
|
|
import "../utils"
|
|
import "core:strings"
|
|
import "core:testing"
|
|
|
|
sample :: `..@@.@@@@.
|
|
@@@.@.@.@@
|
|
@@@@@.@.@@
|
|
@.@@@@..@.
|
|
@@.@@@@.@@
|
|
.@@@@@@@.@
|
|
.@.@.@.@@@
|
|
@.@@@.@@@@
|
|
.@@@@@@@@.
|
|
@.@.@@@.@.`
|
|
|
|
get_surrounding :: proc(lines: []string, x: int, y: int) -> (result: [8]u8) {
|
|
i: uint
|
|
for dy in -1 ..= 1 {
|
|
if y + dy < 0 || y + dy >= len(lines) do continue
|
|
for dx in -1 ..= 1 {
|
|
if x + dx < 0 || x + dx >= len(lines[0]) do continue
|
|
if dy == 0 && dx == 0 {
|
|
continue
|
|
}
|
|
result[i] = lines[y + dy][x + dx]
|
|
i += 1
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
solve_first :: proc(s: string) -> u64 {
|
|
input := s
|
|
num_rolls: u64
|
|
lines := strings.split_lines(input)
|
|
defer delete(lines)
|
|
for y in 0 ..< len(lines) {
|
|
for x in 0 ..< len(lines[0]) {
|
|
if lines[y][x] != '@' do continue
|
|
surrounding := get_surrounding(lines, x, y)
|
|
num_surrounding_rolls: uint
|
|
for c in surrounding {
|
|
if c == '@' do num_surrounding_rolls += 1
|
|
if num_surrounding_rolls == 4 do break
|
|
}
|
|
if num_surrounding_rolls < 4 {
|
|
num_rolls += 1
|
|
}
|
|
}
|
|
}
|
|
return num_rolls
|
|
}
|
|
|
|
@(test)
|
|
solve_first_sample :: proc(t: ^testing.T) {
|
|
testing.expect_value(t, solve_first(sample), 13)
|
|
}
|
|
|
|
@(test)
|
|
solve_first_puzzle :: proc(t: ^testing.T) {
|
|
content := utils.read_file("day4/input.txt")
|
|
defer delete(content)
|
|
testing.expect_value(t, solve_first(content), 1626)
|
|
}
|
|
|
|
Position :: struct {
|
|
x: int,
|
|
y: int,
|
|
}
|
|
|
|
get_removable :: proc(lines: []string) -> (positions: [dynamic]Position) {
|
|
for y in 0 ..< len(lines) {
|
|
for x in 0 ..< len(lines[0]) {
|
|
if lines[y][x] != '@' do continue
|
|
surrounding := get_surrounding(lines, x, y)
|
|
num_surrounding_rolls: uint
|
|
for c in surrounding {
|
|
if c == '@' do num_surrounding_rolls += 1
|
|
if num_surrounding_rolls == 4 do break
|
|
}
|
|
if num_surrounding_rolls < 4 {
|
|
append(&positions, Position{x = x, y = y})
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
solve_second :: proc(s: string) -> (total: u64) {
|
|
s := strings.clone(s)
|
|
defer delete(s)
|
|
lines := strings.split_lines(s)
|
|
defer delete(lines)
|
|
line_len := len(lines[0])
|
|
removed := true
|
|
for removed {
|
|
removed = false
|
|
positions := get_removable(lines)
|
|
defer delete(positions)
|
|
for p in positions {
|
|
removed = true
|
|
raw_data(lines[p.y])[p.x] = '.'
|
|
total += 1
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
@(test)
|
|
solve_second_sample :: proc(t: ^testing.T) {
|
|
testing.expect_value(t, solve_second(sample), 43)
|
|
}
|
|
|
|
@(test)
|
|
solve_second_puzzle :: proc(t: ^testing.T) {
|
|
content := utils.read_file("day4/input.txt")
|
|
defer delete(content)
|
|
testing.expect_value(t, solve_second(content), 9173)
|
|
}
|
|
|