Day 11
This commit is contained in:
parent
5d41e8322b
commit
34bd604d16
2 changed files with 159 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
||||||
*.bin
|
*.bin
|
||||||
*.txt
|
*.txt
|
||||||
|
*.dSYM
|
||||||
|
|
|
||||||
158
d11/main.odin
Normal file
158
d11/main.odin
Normal file
|
|
@ -0,0 +1,158 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "core:unicode/utf8"
|
||||||
|
import "core:math"
|
||||||
|
import "core:slice"
|
||||||
|
import "core:strconv"
|
||||||
|
import "core:strings"
|
||||||
|
import "core:bytes"
|
||||||
|
import "core:fmt"
|
||||||
|
import "core:os"
|
||||||
|
|
||||||
|
import "../util"
|
||||||
|
|
||||||
|
is_inside_boundries :: proc(row_idx, col_idx: int, layout: [][]rune) -> bool {
|
||||||
|
return col_idx >= 0 && col_idx < len(layout[0]) && row_idx >= 0 && row_idx < len(layout)
|
||||||
|
}
|
||||||
|
|
||||||
|
get_adjacent_occupied :: proc(row_idx, col_idx: int, layout: [][]rune) -> i64 {
|
||||||
|
adjacent_occupied: i64 = 0
|
||||||
|
|
||||||
|
for adjacent_row_idx in -1..=1 {
|
||||||
|
for adjacent_col_idx in -1..=1 {
|
||||||
|
if adjacent_col_idx == 0 && adjacent_row_idx == 0 do continue
|
||||||
|
|
||||||
|
neighbour_row_idx := row_idx + adjacent_row_idx
|
||||||
|
neighbour_col_idx := col_idx + adjacent_col_idx
|
||||||
|
|
||||||
|
if is_inside_boundries(neighbour_row_idx, neighbour_col_idx, layout) &&
|
||||||
|
layout[neighbour_row_idx][neighbour_col_idx] == '#' {
|
||||||
|
adjacent_occupied += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return adjacent_occupied
|
||||||
|
}
|
||||||
|
|
||||||
|
get_adjacent_visible :: proc(row_idx, col_idx: int, layout: [][]rune) -> i64 {
|
||||||
|
visible_occupied: i64 = 0
|
||||||
|
|
||||||
|
directions := [8]struct{dr, dc: int}{
|
||||||
|
{-1, -1}, {-1, 0}, {-1, 1},
|
||||||
|
{ 0, -1}, { 0, 1},
|
||||||
|
{ 1, -1}, { 1, 0}, { 1, 1},
|
||||||
|
}
|
||||||
|
for dir in directions {
|
||||||
|
r, c := row_idx + dir.dr, col_idx + dir.dc
|
||||||
|
|
||||||
|
for is_inside_boundries(r, c, layout) {
|
||||||
|
tile := layout[r][c]
|
||||||
|
|
||||||
|
if tile == '#' {
|
||||||
|
visible_occupied += 1
|
||||||
|
break
|
||||||
|
} else if tile == 'L' {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
r += dir.dr
|
||||||
|
c += dir.dc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return visible_occupied
|
||||||
|
}
|
||||||
|
|
||||||
|
part_1 :: proc(lines: []string) {
|
||||||
|
result: i64 = 0
|
||||||
|
|
||||||
|
layout := slice.mapper(lines, proc(line: string) -> []rune {
|
||||||
|
return utf8.string_to_runes(line)
|
||||||
|
})
|
||||||
|
|
||||||
|
changed := true
|
||||||
|
for changed {
|
||||||
|
new_layout := slice.clone(layout)
|
||||||
|
for row, row_idx in layout do new_layout[row_idx] = slice.clone(row)
|
||||||
|
changed = false
|
||||||
|
|
||||||
|
for row, row_idx in layout {
|
||||||
|
for tile, col_idx in row {
|
||||||
|
if tile == '#' {
|
||||||
|
adjacent_occupied := get_adjacent_occupied(row_idx, col_idx, layout)
|
||||||
|
if adjacent_occupied >= 4 {
|
||||||
|
new_layout[row_idx][col_idx] = 'L'
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
} else if tile == 'L' {
|
||||||
|
adjacent_occupied := get_adjacent_occupied(row_idx, col_idx, layout)
|
||||||
|
if adjacent_occupied == 0 {
|
||||||
|
new_layout[row_idx][col_idx] = '#'
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layout = new_layout
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
result = slice.reduce(layout, i64(0), proc(res: i64, row: []rune) -> i64 {
|
||||||
|
return res + i64(slice.count(row, '#'))
|
||||||
|
})
|
||||||
|
fmt.printfln("Part 1: %d", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
part_2 :: proc(lines: []string) {
|
||||||
|
result: i64 = 0
|
||||||
|
|
||||||
|
layout := slice.mapper(lines, proc(line: string) -> []rune {
|
||||||
|
return utf8.string_to_runes(line)
|
||||||
|
})
|
||||||
|
|
||||||
|
changed := true
|
||||||
|
for changed {
|
||||||
|
new_layout := slice.clone(layout)
|
||||||
|
for row, row_idx in layout do new_layout[row_idx] = slice.clone(row)
|
||||||
|
changed = false
|
||||||
|
|
||||||
|
for row, row_idx in layout {
|
||||||
|
for tile, col_idx in row {
|
||||||
|
if tile == '#' {
|
||||||
|
adjacent_occupied := get_adjacent_visible(row_idx, col_idx, layout)
|
||||||
|
if adjacent_occupied >= 5 {
|
||||||
|
new_layout[row_idx][col_idx] = 'L'
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
} else if tile == 'L' {
|
||||||
|
adjacent_occupied := get_adjacent_visible(row_idx, col_idx, layout)
|
||||||
|
if adjacent_occupied == 0 {
|
||||||
|
new_layout[row_idx][col_idx] = '#'
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layout = new_layout
|
||||||
|
}
|
||||||
|
|
||||||
|
result = slice.reduce(layout, i64(0), proc(res: i64, row: []rune) -> i64 {
|
||||||
|
return res + i64(slice.count(row, '#'))
|
||||||
|
})
|
||||||
|
fmt.printfln("Part 2: %d", result)
|
||||||
|
}
|
||||||
|
|
||||||
|
main :: proc() {
|
||||||
|
context.allocator = context.temp_allocator
|
||||||
|
defer free_all(context.temp_allocator)
|
||||||
|
|
||||||
|
INPUT :: #load("input.txt", string)
|
||||||
|
lines := strings.split(INPUT, "\n")
|
||||||
|
lines = lines[:len(lines)-1]
|
||||||
|
|
||||||
|
part_1(lines)
|
||||||
|
part_2(lines)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue