8000 Solve day 22 in Elixir · bereal/AdventOfCode2020@043ebf4 · GitHub
[go: up one dir, main page]

Skip to content

Commit

Permalink
Solve day 22 in Elixir
Browse files Browse the repository at this point in the history
  • Loading branch information
bereal committed Dec 22, 2020
1 parent ddb861c commit 043ebf4
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 1 deletion.
53 changes: 53 additions & 0 deletions 22_elixir/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
Player 1:
2
31
14
45
33
18
29
36
44
47
38
6
9
5
48
17
50
41
4
21
42
23
25
28
3

Player 2:
26
16
27
12
49
32
19
46
37
15
10
30
11
24
1
40
7
8
43
34
20
35
22
39
13
3 changes: 3 additions & 0 deletions 22_elixir/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

elixir ./solve.exs < input.txt
52 changes: 52 additions & 0 deletions 22_elixir/solve.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
defmodule Game do
def play1(a, []), do: {true, a}
def play1([], b), do: {false, b}

def play1([a | as], [b | bs]) do
if a > b, do: play1(as ++ [a, b], bs), else: play1(as, bs ++ [b, a])
end

def play2(p1, p2, mem1 \\ MapSet.new(), mem2 \\ MapSet.new())
def play2(a, [], _, _), do: {true, a}
def play2([], b, _, _), do: {false, b}

def play2([a | as] = p1, [b | bs] = p2, mem1, mem2) do
win = fn p ->
{new_as, new_bs} = if p, do: {as ++ [a, b], bs}, else: {as, bs ++ [b, a]}
play2(new_as, new_bs, MapSet.put(mem1, p1), MapSet.put(mem2, p2))
end

cond do
MapSet.member?(mem1, p1) or MapSet.member?(mem2, p2) ->
{true, p1}

a <= length(as) and b <= length(bs) ->
case play2(Enum.take(as, a), Enum.take(bs, b)) do
{p, _} -> win.(p)
end

true ->
win.(a > b)
end
end

def score({_, deck}) do
Enum.reverse(deck) |> Enum.with_index(1) |> Enum.map(fn {a, b} -> a * b end) |> Enum.sum()
end

def read_player(buf \\ []) do
case IO.read(:stdio, :line) do
e when e in [:eof, "\n"] ->
buf |> Enum.reverse() |> Enum.drop(1) |> Enum.map(&String.to_integer/1)

v ->
read_player([String.trim(v) | buf])
end
end

def read_input(), do: {read_player(), read_player()}
end

{p1, p2} = Game.read_input()
Game.play1(p1, p2) |> Game.score() |> IO.inspect()
Game.play2(p1, p2) |> Game.score() |> IO.inspect()
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ I estimated my knowledge of each language by 0 to 4 scale, roughly meaning:
| 19 | [JavaScript](#day-19-javascript) | 4 | [Monster Messages](https://adventofcode.com/2020/day/19) | [Link](19_js/solve.js) |
| 20 | [Scala](#day-20-scala) | 1 | [Jurassic Jigsaw](https://adventofcode.com/2020/day/20) | [Link](20_scala/solve.scala) |
| 21 | [Dart](#day-21-dart) | 2 | [Allergen Assessment](https://adventofcode.com/2020/day/21) | [Link](21_dart/solve.dart) |
| 22 | [Elixir](#day-22-elixir) | 0 | [Crab Combat](https://adventofcode.com/2020/day/22) | [Link](22_elixir/solve.exs) |

### Day 1: Erlang

Expand Down Expand Up @@ -461,7 +462,7 @@ _TBD after the second part is complete_

### Day 21. Dart

_Knowledge_: 3
_Knowledge_: 2

_Site_: https://dart.dev/

Expand All @@ -476,3 +477,19 @@ On the other hand, TS is able to use all the JS code, which is _a lot_ of code.
The puzzle is essentially the same as on the [day 16](#day-16-c), just differently worded, so the solution is identical.

[Solution](21_dart/solve.dart) | [Up](#languages)


### Day 22. Elixir

_Knowledge_: 0

_Site_: https://elixir-lang.org/

_Puzzle_: [Crab Combat](https://adventofcode.com/2020/day/22). Lists and recursion

Elixir is Erlang in Ruby's clothes. The puzzle is all about recursive list processing, so
a functional language is a no-brainer choice. But all the coolest features, like metaprogramming,
polymorphism, and concurrency remained unexplored. Well, someday... Having to use `fun.()` syntax
for variable-bound functions feels a bit awkward.

[Solution](22_elixir/solve.exs) | [Up](#languages)

0 comments on commit 043ebf4

Please sign in to comment.
0