Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Timeline

exercises/timeline.livemd

Timeline

Mix.install([
  {:jason, "~> 1.4"},
  {:kino, "~> 0.9", override: true},
  {:youtube, github: "brooklinjazz/youtube"},
  {:hidden_cell, github: "brooklinjazz/hidden_cell"}
])

Navigation

Home Report An Issue ItineraryStrings And Binaries

Timeline

You are building an application which creates a timeline of events. Users provide you with a list of Dates. You will provide the number of days between each date.

dates = [~D[2020-01-01], ~D[2020-01-02], ~D[2020-01-22]]

Timeline.from_dates(dates)
[1, 20]

BONUS: Timeline.from_strings/1.

As a bonus, implement the Timeline.from_strings/1 function which accepts a list of strings instead of a list of Dates.

date_strings = ["2020-01-01", "2020-01-02", "2020-01-22"]

Timeline.from_strings(date_strings)
[1, 20]

Example Solution

defmodule Timeline do
  
  def from_dates(dates) do
    Enum.chunk_every(dates, 2, 1, :discard)
    |> Enum.map(fn chunk ->
      [start, finish] = chunk
      Date.diff(finish, start)
    end)
  end

  def from_strings(date_strings) do
    date_strings
    |> Enum.map(&string_to_date/1)
    |> from_dates()
  end

  defp string_to_date(date_string) do
    [year, month, day] = String.split(date_string, "-")
    Date.new!(String.to_integer(year), String.to_integer(month), String.to_integer(day))
  end
end

Alternatively, you might use Date.from_iso8601/1 to convert strings into Date structs instead of creating your own solution as seen above.

def from_strings(date_strings) do
    Enum.map(date_strings, &Date.from_iso8601!/1)
    |> from_dates()
end

Enter your solution below.

defmodule Timeline do
  @moduledoc """
  Documentation for `Timeline`
  """

  @doc """
  Given a list of [Date](https://hexdocs.pm/elixir/Date.html)s return a timeline of days between each date.

  ## Examples

    iex> Timeline.from_dates([~D[2020-01-01]])
    []

    iex> Timeline.from_dates([~D[2020-01-01], ~D[2020-01-02]])
    [1]

    iex> Timeline.from_dates([~D[2020-01-01], ~D[2020-01-02], ~D[2020-01-22]])
    [1, 20]
    
    iex> Timeline.from_dates([~D[2020-01-01], ~D[2020-01-10], ~D[2020-01-22], ~D[2020-01-24]])
    [9, 12, 2]
  """
  def from_dates(dates) do
    Enum.chunk_every(dates, 2, 1, :discard)
    |> Enum.map(fn chunk -> 
      [first, last] = chunk
      Date.diff(last, first)
    end)
  end

  @doc """
  Given a list of "YYYY-MM-DD" strings return a timeline of days between each date.
  Assume you will always be given two or more strings.

  ## Examples

    iex> Timeline.from_strings(["2020-01-01", "2020-01-02"])
    [1]

    iex> Timeline.from_strings(["2020-01-01", "2020-01-02", "2020-01-22"])
    [1, 20]
    
    iex> Timeline.from_strings(["2020-01-01", "2020-01-10", "2020-01-22", "2020-01-24"])
    [9, 12, 2]
  """
  def from_strings(date_strings) do
    array = Enum.chunk_every(date_strings, 2, 1, :discard)
    |> Enum.map(fn chunk -> 
      [first, last] = chunk
      
      Date.diff(string_to_date(last), string_to_date(first))
    end)
    
  end

  def string_to_date(date_string) do
    {:ok, date} = Date.from_iso8601(date_string)
    date
  end
end

Commit Your Progress

DockYard Academy now recommends you use the latest Release rather than forking or cloning our repository.

Run git status to ensure there are no undesirable changes. Then run the following in your command line from the curriculum folder to commit your progress.

$ git add .
$ git commit -m "finish Timeline exercise"
$ git push

We’re proud to offer our open-source curriculum free of charge for anyone to learn from at their own pace.

We also offer a paid course where you can learn from an instructor alongside a cohort of your peers. We will accept applications for the June-August 2023 cohort soon.

Navigation

Home Report An Issue ItineraryStrings And Binaries