Add solution for 2021 day 11

This commit is contained in:
Patrick Auernig 2021-12-11 16:21:34 +01:00
parent ea82ee5cd0
commit 6b80075f36
8 changed files with 153 additions and 28 deletions

View File

@ -3,7 +3,7 @@
## Progress
| Day | Part 1 | Part 2 | Language |
| :-: | :----: | :----: | :------- |
| :-: | :----: | :----: | :-------- |
| 01 | ✓ | ✓ | [Ruby] |
| 02 | ✓ | ✓ | [Ada] |
| 03 | ✓ | ✓ | [Perl] |
@ -14,7 +14,7 @@
| 08 | ✓ | ✓ | [C#] |
| 09 | ✓ | ✓ | [C] |
| 10 | ✓ | ✓ | [OCaml] |
| 11 | | | |
| 11 | ✓ | ✓ | [Crystal] |
| 12 | | | |
| 13 | | | |
| 14 | | | |
@ -46,3 +46,4 @@
[c#]: https://docs.microsoft.com/en-us/dotnet/csharp/
[c]: http://www.open-std.org/jtc1/sc22/wg14
[ocaml]: https://ocaml.org
[crystal]: https://crystal-lang.org

6
2021/day-11/Justfile Normal file
View File

@ -0,0 +1,6 @@
@part PART INPUT_FILE="inputs/puzzle.txt":
crystal build --error-trace part_{{PART}}.cr
./part_{{PART}} {{INPUT_FILE}}
clean:
rm -f part_one part_two

70
2021/day-11/common.cr Normal file
View File

@ -0,0 +1,70 @@
alias OctopusMap = Array(Array(Int32))
alias FlashMap = Array(Array(Bool))
SURROUNDING = [-1, 0, 1]
.repeated_permutations(2)
.reject { |v| v == [0, 0] }
.map { |v| Tuple(Int32, Int32).from(v) }
.to_set
def parse_file(path : String) : OctopusMap
File.read_lines(path, chomp: true).map &.chars.map(&.to_i)
end
def print_map(octopi : OctopusMap)
puts "-" * octopi.first.size
octopi.each do |row|
puts row
end
puts "-" * octopi.first.size
end
def flash(x : Int32, y : Int32, octopi : OctopusMap, flashes : FlashMap) : Int32
flashes[y][x] = true
octopi[y][x] = 0
return 1 + mark_surrounding(x, y, octopi, flashes) do |nx, ny|
next 0 if flashes[ny][nx]
next flash(nx, ny, octopi, flashes) if octopi[ny][nx] > 9
0
end
end
def mark_surrounding(x : Int32, y : Int32, octopi : OctopusMap, flashes : FlashMap) : Int32
valid_surrounding = SURROUNDING.reject do |(dx, dy)|
val = false
val ||= dx == -1 if x == 0
val ||= dx == 1 if x == octopi.first.size - 1
val ||= dy == -1 if y == 0
val ||= dy == 1 if y == octopi.size - 1
val
end
return valid_surrounding.sum do |(dx, dy)|
octopi[y + dy][x + dx] += 1 unless flashes[y + dy][x + dx]
yield x + dx, y + dy
end
end
def generation(octopi : OctopusMap, flashes : FlashMap) : Int32
gen_flash_count = 0
octopi.each_with_index do |row, y|
row.each_with_index do |_, x|
next if flashes[y][x]
octopi[y][x] += 1
gen_flash_count += flash(x, y, octopi, flashes) if octopi[y][x] > 9
end
end
gen_flash_count
end
def generations(steps : Int32, octopi : OctopusMap, flashes : FlashMap, flash_count : Int32) : Int32
return flash_count if steps == 0
flash_count += generation(octopi, flashes)
flashes = octopi.map &.map { false }
return generations(steps - 1, octopi, flashes, flash_count)
end

View File

@ -0,0 +1,10 @@
4134384626
7114585257
1582536488
4865715538
5733423513
8532144181
1288614583
2248711141
6415871681
7881531438

View File

@ -0,0 +1,10 @@
5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526

10
2021/day-11/part_one.cr Normal file
View File

@ -0,0 +1,10 @@
require "./common"
def main(path)
octopi = parse_file(path)
flashes = octopi.map &.map { false }
puts generations(100, octopi, flashes, 0)
end
main(ARGV.first)

18
2021/day-11/part_two.cr Normal file
View File

@ -0,0 +1,18 @@
require "./common"
def main(path)
octopi = parse_file(path)
req_flashes = octopi.size * octopi.first.size
(1..).each do |generation|
flashes = octopi.map &.map { false }
gen_flashes = generation(octopi, flashes)
if gen_flashes == req_flashes
puts generation
break
end
end
end
main(ARGV.first)

View File

@ -8,4 +8,4 @@
- [2018](2018/README.md) (0% completed)
- [2019](2019/README.md) (0% completed)
- [2020](2020/README.md) (16% completed)
- [2021](2021/README.md) (40% completed)
- [2021](2021/README.md) (44% completed)