diff options
author | Tomasz Chojnacki <tomaszchojnacki2001@gmail.com> | 2023-07-23 19:46:22 +0200 |
---|---|---|
committer | Tomasz Chojnacki <tomaszchojnacki2001@gmail.com> | 2023-07-23 19:46:22 +0200 |
commit | 5d478156035921ef4ca4bba204a0e7a29d72e56e (patch) | |
tree | eba73176ec3b0cc124aee94d5d44f1793d59be0d | |
parent | 7f22307499f6b513e182c7d3a367381179befecf (diff) | |
download | gleam_aoc2020-5d478156035921ef4ca4bba204a0e7a29d72e56e.tar.gz gleam_aoc2020-5d478156035921ef4ca4bba204a0e7a29d72e56e.zip |
Solve part 1 of day 22
-rw-r--r-- | aoc-2020-gleam/src/days/day22.gleam | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/aoc-2020-gleam/src/days/day22.gleam b/aoc-2020-gleam/src/days/day22.gleam new file mode 100644 index 0000000..5c72847 --- /dev/null +++ b/aoc-2020-gleam/src/days/day22.gleam @@ -0,0 +1,80 @@ +import gleam/io +import gleam/int +import gleam/list +import gleam/bool +import gleam/string as str +import gleam/function as fun +import gleam/order.{Eq, Gt, Lt} +import ext/resultx as resx +import util/input_util + +type GameState { + GameState(player1: List(Int), player2: List(Int)) +} + +fn parse_game_state(input: String) -> GameState { + let assert [player1, player2] = + input + |> str.trim() + |> str.split("\n\n") + |> list.map(with: fn(part) { + part + |> str.split("\n") + |> list.rest + |> resx.assert_unwrap + |> list.map(with: fun.compose(int.parse, resx.assert_unwrap)) + }) + + GameState(player1, player2) +} + +fn score(deck: List(Int)) -> Int { + deck + |> list.reverse + |> list.index_fold( + from: 0, + with: fn(sum, card, index) { sum + card * { index + 1 } }, + ) +} + +fn play_combat_round(previous: GameState) -> Result(GameState, Int) { + let assert [top1, ..rest1] = previous.player1 + let assert [top2, ..rest2] = previous.player2 + + let #(new1, new2) = case int.compare(top1, top2) { + Lt -> #(rest1, list.append(rest2, [top2, top1])) + Eq -> panic + Gt -> #(list.append(rest1, [top1, top2]), rest2) + } + + use <- bool.guard(when: new1 == [], return: Error(score(new2))) + use <- bool.guard(when: new2 == [], return: Error(score(new1))) + + Ok(GameState(new1, new2)) +} + +fn play_combat_game(initial: GameState) -> Int { + case play_combat_round(initial) { + Ok(next) -> play_combat_game(next) + Error(score) -> score + } +} + +fn part1(input: String) -> Int { + input + |> parse_game_state + |> play_combat_game + |> int.absolute_value +} + +pub fn main() -> Nil { + let test = input_util.read_text("test22") + let assert 306 = part1(test) + // let assert 291 = part2(test) + + let input = input_util.read_text("day22") + io.debug(part1(input)) + // io.debug(part2(input)) + + Nil +} |