Skip to content

Instantly share code, notes, and snippets.

@ynonp
Created December 22, 2020 18:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ynonp/60af5cb87212fa345ed2a58e656ea210 to your computer and use it in GitHub Desktop.
Save ynonp/60af5cb87212fa345ed2a58e656ea210 to your computer and use it in GitHub Desktop.
defmodule Day22_2 do
def read_input do
File.read!("input/day22.txt")
|> String.split("\n\n", trim: true)
|> Enum.map(fn deck_str ->
deck_str
|> String.split("\n", trim: true)
|> Enum.drop(1)
|> Enum.map(&String.to_integer/1)
end)
|> List.to_tuple
end
def finalize_round({ :p1, _deck }, [top1 | rest1], [top2 | rest2]) do
{
rest1 ++ [top1, top2],
rest2
}
end
def finalize_round({ :p2, _deck }, [top1 | rest1], [top2 | rest2]) do
{
rest1,
rest2 ++ [top2, top1]
}
end
def play({[top1 | rest1] = deck1, [top2 | rest2] = deck2}, seen) do
cond do
MapSet.member?(seen, { deck1, deck2 }) -> { :p1, deck1 }
(top1 <= Enum.count(rest1)) && (top2 <= Enum.count(rest2)) ->
play({ Enum.take(rest1, top1), Enum.take(rest2, top2) }, MapSet.new)
|> finalize_round(deck1, deck2)
|> play(MapSet.put(seen, { deck1, deck2 }))
true ->
finalize_round({
(if top1 > top2, do: :p1, else: :p2),
(if top1 > top2, do: deck1, else: deck2)
}, deck1, deck2)
|> play(MapSet.put(seen, { deck1, deck2 }))
end
end
def play({[], deck2}, _seen) do
{ :p2, deck2 }
end
def play({deck1, []}, _seen) do
{ :p1, deck1 }
end
def score(deck) do
deck
|> Enum.reverse
|> Enum.with_index(1)
|> Enum.map(fn { card, index } -> card * index end)
|> Enum.sum
end
def part1 do
{ winner, deck } = read_input()
|> play(MapSet.new)
IO.inspect(score(deck))
end
end
defmodule Day22 do
def read_input do
File.read!("input/day22.txt")
|> String.split("\n\n", trim: true)
|> Enum.map(fn deck_str ->
deck_str
|> String.split("\n", trim: true)
|> Enum.drop(1)
|> Enum.map(&String.to_integer/1)
end)
|> List.to_tuple
end
def play({[top1 | rest1], [top2 | rest2]}) when top1 > top2 do
{
rest1 ++ [top1, top2],
rest2
}
|> play
end
def play({[top1 | rest1], [top2 | rest2]}) when top2 > top1 do
{
rest1,
rest2 ++ [top2, top1],
}
|> play
end
def play({[], deck}) do
deck
end
def play({deck, []}) do
deck
end
def score(deck) do
deck
|> Enum.reverse
|> Enum.with_index(1)
|> Enum.map(fn { card, index } -> card * index end)
|> Enum.sum
end
def part1 do
read_input()
|> play
|> score
|> IO.inspect
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment