> For the complete documentation index, see [llms.txt](https://elixir.petrolidas.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://elixir.petrolidas.com/exhort/day-17.md).

# Day 17

## Exercises

* [x] [Boutique Suggestions](#boutique-suggestions)
* [x] [Community Garden](#community-garden)
* [x] [Bread And Potions](#bread-and-potions)

### Boutique Suggestions

[Exercise on Exercism](https://exercism.org/tracks/elixir/exercises/boutique-suggestions) **|** [View my solution](https://exercism.org/tracks/elixir/exercises/boutique-suggestions/solutions/petros)

#### Solution

<details>

<summary>Expand to see code (spoiler alert)</summary>

{% code lineNumbers="true" %}

```elixir
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

```

{% endcode %}

[View gist on GitHub](https://gist.github.com/petros/d6631a35a83dde4019024667c6a1a1d3)

</details>

#### Notes

### Community Garden

[Exercise on Exercism](https://exercism.org/tracks/elixir/exercises/community-garden) **|** [View my solution](https://exercism.org/tracks/elixir/exercises/community-garden/solutions/petros)

#### Solution

<details>

<summary>Expand to see code (spoiler alert)</summary>

{% code lineNumbers="true" %}

```elixir
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

```

{% endcode %}

[View gist on GitHub](https://gist.github.com/petros/2476a9647535d8459a7b5f4973ec558a)

</details>

#### Notes

### Bread and Potions

[Exercise on Exercism](https://exercism.org/tracks/elixir/exercises/bread-and-potions) **|** [View my solution](https://exercism.org/tracks/elixir/exercises/bread-and-potions/solutions/petros)

#### Solution

<details>

<summary>Expand to see code (spoiler alert)</summary>

{% code lineNumbers="true" %}

```elixir
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

```

{% endcode %}

[View gist on GitHub](https://gist.github.com/petros/2d1b7a62e01f005244eaf68971126a82)

</details>

#### Notes

## Overall progress

<figure><img src="/files/uVqtj6NU6EFTfMXU0I46" alt="An image showing my progress on Exercism. It&#x27;s 19.9% as of Wednesday, 24 August 2022."><figcaption><p>Progress</p></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://elixir.petrolidas.com/exhort/day-17.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
