diff options
Diffstat (limited to 'aoc-2020-gleam/src/days/day24.gleam')
-rw-r--r-- | aoc-2020-gleam/src/days/day24.gleam | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/aoc-2020-gleam/src/days/day24.gleam b/aoc-2020-gleam/src/days/day24.gleam index 66bedb8..f380530 100644 --- a/aoc-2020-gleam/src/days/day24.gleam +++ b/aoc-2020-gleam/src/days/day24.gleam @@ -1,13 +1,14 @@ import gleam/io -import gleam/set +import gleam/bool import gleam/list +import gleam/set.{type Set} import ext/setx import ext/resultx as resx import util/input_util import util/parser as p import util/hex.{type Hex} -fn parse_tiles(lines: List(String)) -> List(Hex) { +fn parse_flips(lines: List(String)) -> List(Hex) { let tile_parser = [ p.replace(p.literal("e"), with: hex.e), @@ -28,20 +29,50 @@ fn parse_tiles(lines: List(String)) -> List(Hex) { }) } +fn get_black_tiles(flips: List(Hex)) -> Set(Hex) { + list.fold(over: flips, from: set.new(), with: setx.toggle) +} + +fn cycle(prev: Set(Hex), times: Int) -> Set(Hex) { + use <- bool.guard(when: times == 0, return: prev) + + prev + |> setx.flat_map(with: hex.neighbours7) + |> set.fold(from: set.new(), with: fn(acc, tile) { + let was_black = set.contains(in: prev, this: tile) + let adjacent = + tile + |> hex.neighbours6 + |> set.intersection(prev) + |> set.size + + case #(was_black, adjacent) { + #(True, 1) | #(_, 2) -> set.insert(into: acc, this: tile) + _ -> acc + } + }) + |> cycle(times - 1) +} + fn part1(lines: List(String)) -> Int { - let tiles = parse_tiles(lines) - let blacks = list.fold(over: tiles, from: set.new(), with: setx.toggle) - set.size(blacks) + lines + |> parse_flips + |> get_black_tiles + |> set.size } -fn part2(lines: List(String)) -> Nil { - Nil +fn part2(lines: List(String)) -> Int { + lines + |> parse_flips + |> get_black_tiles + |> cycle(100) + |> set.size } pub fn main() -> Nil { let testing = input_util.read_lines("test24") let assert 10 = part1(testing) - io.debug(part2(testing)) + let assert 2208 = part2(testing) let input = input_util.read_lines("day24") io.debug(part1(input)) |