From 6b80075f36cf85b32ab4073c2851be2a588daf8f Mon Sep 17 00:00:00 2001 From: Patrick Auernig Date: Sat, 11 Dec 2021 16:21:34 +0100 Subject: [PATCH] Add solution for 2021 day 11 --- 2021/README.md | 55 +++++++++++++-------------- 2021/day-11/Justfile | 6 +++ 2021/day-11/common.cr | 70 +++++++++++++++++++++++++++++++++++ 2021/day-11/inputs/puzzle.txt | 10 +++++ 2021/day-11/inputs/sample.txt | 10 +++++ 2021/day-11/part_one.cr | 10 +++++ 2021/day-11/part_two.cr | 18 +++++++++ README.md | 2 +- 8 files changed, 153 insertions(+), 28 deletions(-) create mode 100644 2021/day-11/Justfile create mode 100644 2021/day-11/common.cr create mode 100644 2021/day-11/inputs/puzzle.txt create mode 100644 2021/day-11/inputs/sample.txt create mode 100644 2021/day-11/part_one.cr create mode 100644 2021/day-11/part_two.cr diff --git a/2021/README.md b/2021/README.md index f92b694..36ecdbb 100644 --- a/2021/README.md +++ b/2021/README.md @@ -2,33 +2,33 @@ ## Progress -| Day | Part 1 | Part 2 | Language | -| :-: | :----: | :----: | :------- | -| 01 | ✓ | ✓ | [Ruby] | -| 02 | ✓ | ✓ | [Ada] | -| 03 | ✓ | ✓ | [Perl] | -| 04 | ✓ | ✓ | [Go] | -| 05 | ✓ | ✓ | [Nim] | -| 06 | ✓ | ✓ | [Inko] | -| 07 | ✓ | ✓ | [Swift] | -| 08 | ✓ | ✓ | [C#] | -| 09 | ✓ | ✓ | [C] | -| 10 | ✓ | ✓ | [OCaml] | -| 11 | | | | -| 12 | | | | -| 13 | | | | -| 14 | | | | -| 15 | | | | -| 16 | | | | -| 17 | | | | -| 18 | | | | -| 19 | | | | -| 20 | | | | -| 21 | | | | -| 22 | | | | -| 23 | | | | -| 24 | | | | -| 25 | | | | +| Day | Part 1 | Part 2 | Language | +| :-: | :----: | :----: | :-------- | +| 01 | ✓ | ✓ | [Ruby] | +| 02 | ✓ | ✓ | [Ada] | +| 03 | ✓ | ✓ | [Perl] | +| 04 | ✓ | ✓ | [Go] | +| 05 | ✓ | ✓ | [Nim] | +| 06 | ✓ | ✓ | [Inko] | +| 07 | ✓ | ✓ | [Swift] | +| 08 | ✓ | ✓ | [C#] | +| 09 | ✓ | ✓ | [C] | +| 10 | ✓ | ✓ | [OCaml] | +| 11 | ✓ | ✓ | [Crystal] | +| 12 | | | | +| 13 | | | | +| 14 | | | | +| 15 | | | | +| 16 | | | | +| 17 | | | | +| 18 | | | | +| 19 | | | | +| 20 | | | | +| 21 | | | | +| 22 | | | | +| 23 | | | | +| 24 | | | | +| 25 | | | | ## Additional Challenges @@ -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 diff --git a/2021/day-11/Justfile b/2021/day-11/Justfile new file mode 100644 index 0000000..1b34677 --- /dev/null +++ b/2021/day-11/Justfile @@ -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 diff --git a/2021/day-11/common.cr b/2021/day-11/common.cr new file mode 100644 index 0000000..4a4b8b7 --- /dev/null +++ b/2021/day-11/common.cr @@ -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 diff --git a/2021/day-11/inputs/puzzle.txt b/2021/day-11/inputs/puzzle.txt new file mode 100644 index 0000000..1a0fab9 --- /dev/null +++ b/2021/day-11/inputs/puzzle.txt @@ -0,0 +1,10 @@ +4134384626 +7114585257 +1582536488 +4865715538 +5733423513 +8532144181 +1288614583 +2248711141 +6415871681 +7881531438 diff --git a/2021/day-11/inputs/sample.txt b/2021/day-11/inputs/sample.txt new file mode 100644 index 0000000..03743f6 --- /dev/null +++ b/2021/day-11/inputs/sample.txt @@ -0,0 +1,10 @@ +5483143223 +2745854711 +5264556173 +6141336146 +6357385478 +4167524645 +2176841721 +6882881134 +4846848554 +5283751526 diff --git a/2021/day-11/part_one.cr b/2021/day-11/part_one.cr new file mode 100644 index 0000000..dd7a8c1 --- /dev/null +++ b/2021/day-11/part_one.cr @@ -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) diff --git a/2021/day-11/part_two.cr b/2021/day-11/part_two.cr new file mode 100644 index 0000000..b443e04 --- /dev/null +++ b/2021/day-11/part_two.cr @@ -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) diff --git a/README.md b/README.md index e188ad2..38b14bc 100644 --- a/README.md +++ b/README.md @@ -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)