🗓️Day 17

Wednesday, 24 August 2022 - Day 17 of Exhort August 2022 - Exercism (My Elixir Journey)

Exercises

Boutique Suggestions

Exercise on Exercism | View my solution

Solution

Expand to see code (spoiler alert)
defmodule BoutiqueSuggestions do
  def get_combinations(tops, bottoms, options \\ []) do
    mp = Keyword.get(options, :maximum_price, 100.0)

    for x <- tops,
        y <- bottoms,
        x.base_color != y.base_color and x.price + y.price <= mp do
      {x, y}
    end
  end
end

View gist on GitHub

Notes

Community Garden

Exercise on Exercism | View my solution

Solution

Expand to see code (spoiler alert)
defmodule Plot do
  @enforce_keys [:plot_id, :registered_to]
  defstruct [:plot_id, :registered_to]
end

defmodule CommunityGarden do
  @spec start(Keyword.t()) :: tuple()
  def start(opts \\ []) do
    Agent.start(fn -> [] end, opts)
  end

  @spec list_registrations(pid()) :: list(Plot)
  def list_registrations(pid) do
    Agent.get(pid, fn state -> state end)
  end

  @spec register(pid(), String.t()) :: Plot
  def register(pid, register_to) do
    Agent.update(pid, fn state ->
      [%Plot{plot_id: get_next_id(state), registered_to: register_to} | state]
    end)

    Agent.get(pid, fn state ->
      [head | _tail] = state
      head
    end)
  end

  defp get_next_id([]), do: 1
  defp get_next_id(plots), do: Enum.sort_by(plots, & &1.plot_id)

  @spec release(pid(), integer()) :: :ok
  def release(pid, plot_id) do
    Agent.update(pid, fn state ->
      Enum.filter(state, fn plot -> plot.plot_id != plot_id end)
    end)
  end

  @spec get_registration(pid(), integer()) :: tuple() | Plot
  def get_registration(pid, plot_id) do
    plot =
      Agent.get(pid, fn state ->
        Enum.find(state, nil, fn plot -> plot.plot_id == plot_id end)
      end)

    cond do
      plot == nil -> {:not_found, "plot is unregistered"}
      true -> plot
    end
  end
end

View gist on GitHub

Notes

Bread and Potions

Exercise on Exercism | View my solution

Solution

Expand to see code (spoiler alert)
defmodule RPG do
  defmodule Character do
    defstruct health: 100, mana: 0
  end

  defmodule LoafOfBread do
    defstruct []
  end

  defmodule ManaPotion do
    defstruct strength: 10
  end

  defmodule Poison do
    defstruct []
  end

  defmodule EmptyBottle do
    defstruct []
  end

  defprotocol Edible do
    @spec eat(t(), %RPG.Character{}) :: any()
    def eat(item, character)
  end

  defimpl Edible, for: LoafOfBread do
    @spec eat(%RPG.LoafOfBread{}, %RPG.Character{}) :: {nil, %RPG.Character{}}
    def eat(_item, character), do: {nil, %Character{character | health: character.health + 5}}
  end

  defimpl Edible, for: ManaPotion do
    @spec eat(%RPG.ManaPotion{}, %RPG.Character{}) :: {%RPG.EmptyBottle{}, %RPG.Character{}}
    def eat(item, character),
      do: {%RPG.EmptyBottle{}, %Character{character | mana: character.mana + item.strength}}
  end

  defimpl Edible, for: Poison do
    @spec eat(%RPG.Poison{}, %RPG.Character{}) :: {%RPG.EmptyBottle{}, %RPG.Character{}}
    def eat(_item, character), do: {%RPG.EmptyBottle{}, %Character{character | health: 0}}
  end
end

View gist on GitHub

Notes

Overall progress

Last updated