# Day 16

## Exercises

* [x] [Newsletter](#newsletter)
* [x] [Chessboard](#chessboard)
* [x] [Remote Control Car](#remote-control-car)

### Newsletter

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

#### Solution

<details>

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

{% code lineNumbers="true" %}

```elixir
defmodule Newsletter do
  @spec read_emails(path :: String.t()) :: list(String.t())
  def read_emails(path) do
    {:ok, contents} = File.read(path)
    String.split(contents, "\n", trim: true)
  end

  @spec open_log(path :: String.t()) :: pid()
  def open_log(path) do
    File.open!(path, [:write])
  end

  @spec log_sent_email(pid(), email :: String.t()) :: :ok
  def log_sent_email(pid, email) do
    IO.puts(pid, email)
  end

  @spec close_log(pid()) :: :ok
  def close_log(pid) do
    File.close(pid)
  end

  @spec send_newsletter(String.t(), String.t(), fun()) :: :ok
  def send_newsletter(emails_path, log_path, send_fun) do
    pid = open_log(log_path)

    read_emails(emails_path)
    |> Enum.each(fn email -> if :ok == send_fun.(email), do: log_sent_email(pid, email) end)

    close_log(pid)
  end
end

```

{% endcode %}

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

</details>

#### Notes

I had to use `File.open!` and I could have used `IO.puts` to avoid having to concatenate a `\n`.

### Chessboard

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

#### Solution

<details>

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

{% code lineNumbers="true" %}

```elixir
defmodule Chessboard do
  @spec rank_range :: Range.t()
  def rank_range, do: 1..8

  @spec file_range :: Range.t()
  def file_range, do: ?A..?H

  @spec ranks :: list(integer())
  def ranks, do: Enum.to_list(rank_range())

  @spec files :: list(String.t())
  def files, do: Enum.map(file_range(), &<<&1>>)
end

```

{% endcode %}

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

</details>

#### Notes

I really love the shorthand: `Enum.map(file_range(), &<<&1>>)`

### Remote Control Car

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

#### Solution

<details>

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

{% code lineNumbers="true" %}

```elixir
defmodule RemoteControlCar do
  @enforce_keys [:nickname]
  defstruct [:nickname, battery_percentage: 100, distance_driven_in_meters: 0]

  @spec new(String.t()) :: struct()
  def new(nickname \\ "none") do
    %RemoteControlCar{nickname: nickname}
  end

  @spec display_distance(remote_car :: struct()) :: String.t()
  def display_distance(%RemoteControlCar{} = remote_car) do
    "#{remote_car.distance_driven_in_meters} meters"
  end

  @spec display_battery(remote_car :: struct()) :: String.t()
  def display_battery(%RemoteControlCar{battery_percentage: 0}), do: "Battery empty"

  def display_battery(%RemoteControlCar{} = remote_car),
    do: "Battery at #{remote_car.battery_percentage}%"

  @spec drive(remote_car :: struct()) :: struct()
  def drive(%RemoteControlCar{battery_percentage: 0} = remote_car), do: remote_car

  def drive(%RemoteControlCar{} = remote_car) do
    %{
      remote_car
      | battery_percentage: remote_car.battery_percentage - 1,
        distance_driven_in_meters: remote_car.distance_driven_in_meters + 20
    }
  end
end

```

{% endcode %}

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

</details>

#### Notes

I didn't know about the `@enforce_keys` module attribute.

## Overall progress

<figure><img src="https://722931016-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FDUq5E45vIeUDn4lY3Psn%2Fuploads%2FiQrbVxef0o2vWB7W0PJz%2F20220823-exhort-day16-progress.png?alt=media&#x26;token=92ecd90d-f849-4e38-b49d-34240c8181fb" alt="An image showing my progress on Exercism. It&#x27;s 17.9% as of Tuesday, 23 August 2022."><figcaption><p>Progress</p></figcaption></figure>
