Advent of Code 2020 in Elixir - Day 23

Crab Cups

defmodule Aoc2020.Day23 do
  @moduledoc "Crab Cups"

  def run() do
    part_1()
  end

  def part_1() do
    cups = parse_input()

    Enum.reduce(0..99, cups, fn _, acc -> play_round(acc) end)
    |> Enum.chunk_by(fn x -> x == 1 end)
    |> (fn
          [second, [1], first] -> Enum.join(first ++ second)
          [[1], rest] -> Enum.join(rest)
          [rest, [1]] -> Enum.join(rest)
        end).()
  end

  def part_2() do
  end

  def parse_input() do
    "219748365"
    |> String.codepoints()
    |> Enum.map(&String.to_integer/1)
  end

  def play_round([current | rest]) do
    {take_3, remaining} = Enum.split(rest, 3)
    in_play = remaining ++ [current]
    destination = destination(current, in_play)
    {pre, post} = Enum.split(in_play, destination + 1)
    pre ++ take_3 ++ post
  end

  def destination(current, remaining) do
    if current < Enum.min(remaining) do
      Enum.find_index(remaining, fn x -> x == Enum.max(remaining) end)
    else
      case Enum.find_index(remaining, fn x -> x == current - 1 end) do
        nil -> destination(current - 1, remaining)
        index -> index
      end
    end
  end
end