exercism/elixir/boutique-suggestions
Danil Negrienko e2e3430ef8 boutique-suggestions 2023-12-23 00:17:15 -05:00
..
.exercism boutique-suggestions 2023-12-23 00:17:15 -05:00
lib boutique-suggestions 2023-12-23 00:17:15 -05:00
test boutique-suggestions 2023-12-23 00:17:15 -05:00
.formatter.exs boutique-suggestions 2023-12-23 00:17:15 -05:00
.gitignore boutique-suggestions 2023-12-23 00:17:15 -05:00
HELP.md boutique-suggestions 2023-12-23 00:17:15 -05:00
HINTS.md boutique-suggestions 2023-12-23 00:17:15 -05:00
README.md boutique-suggestions 2023-12-23 00:17:15 -05:00
mix.exs boutique-suggestions 2023-12-23 00:17:15 -05:00

README.md

Boutique Suggestions

Welcome to Boutique Suggestions on Exercism's Elixir Track. If you need help running the tests or submitting your code, check out HELP.md. If you get stuck on the exercise, check out HINTS.md, but try and solve it without using those first :)

Introduction

List Comprehensions

Comprehensions provide a facility for transforming Enumerables easily and declaratively.

To declare a very simple comprehension, we can use the for keyword followed by a generator and a do-block which creates the new values from the enumerated values.

for n <- [0, 1, 2, 3], do: n + 1
# => [1, 2, 3, 4]

Comprehensions can also have filters. Values that do not pass the filter are removed from the final list:

for n <- [0, 1, 2, 3], n > 1, do: n + 1
# => [3, 4]

We can declare more complicated comprehensions over several lines:

for {atom, number} <- [a: 1, b: 2, c: 3, d: 4],
    rem(number, 2) == 0 do
  atom
end
# => [:b, :d]

A cartesian product can be created using multiple generators. That means that each value generated by the first generator will be paired once with each value generated by the second generator:

for x <- [0, 1],
    y <- [0, 1] do
  {x, y}
end
# => [{0, 0}, {0, 1}, {1, 0}, {1, 1}]

Instructions

Your work at the online fashion boutique store continues. You come up with the idea for a website feature where an outfit is suggested to the user. While you want to give lots of suggestions, you don't want to give bad suggestions, so you decide to use a list comprehension since you can easily generate outfit combinations, then filter them by some criteria.

Clothing items are stored as a map:

%{
  item_name: "Descriptive Name",
  price: 99.00,
  base_color: "red"
}

1. Suggest a combination

Implement get_combinations/3 to take a list of tops, a list of bottoms, and keyword list of options. For now, set options to default to an empty keyword list. The function should return the cartesian product of the lists.

tops = [
  %{item_name: "Dress shirt"},
  %{item_name: "Casual shirt"}
]
bottoms = [
  %{item_name: "Jeans"},
  %{item_name: "Dress trousers"}
]
BoutiqueSuggestions.get_combinations(tops, bottoms)
# => [
#      {%{item_name: "Dress shirt"}, %{item_name: "Jeans"}},
#      {%{item_name: "Dress shirt"}, %{item_name: "Dress trousers"}},
#      {%{item_name: "Casual shirt"}, %{item_name: "Jeans"}},
#      {%{item_name: "Casual shirt"}, %{item_name: "Dress trousers"}}
#    ]

2. Filter out clashing outfits

Each piece of clothing has a :base_color field, use this field to filter out all combinations where the top and the bottom have the same base color.

tops = [
  %{item_name: "Dress shirt", base_color: "blue"},
  %{item_name: "Casual shirt", base_color: "black"}
]
bottoms = [
  %{item_name: "Jeans", base_color: "blue"},
  %{item_name: "Dress trousers", base_color: "black"}
]
BoutiqueSuggestions.get_combinations(tops, bottoms)
# => [
#      {%{item_name: "Dress shirt", base_color: "blue"},
#       %{item_name: "Dress trousers", base_color: "black"}},
#      {%{item_name: "Casual shirt", base_color: "black"},
#       %{item_name: "Jeans", base_color: "blue"}}
#    ]

3. Filter by combination price

Each piece of clothing has a :price field associated with it. While you want to give lots of suggestions, you want to be able to provide users an opportunity to select a price within their budget. From the keyword list of options, use :maximum_price to filter out combinations where the price of the top and bottom exceed the maximum price.

If no maximum_price is specified, the default should be 100.00

tops = [
  %{item_name: "Dress shirt", base_color: "blue", price: 35},
  %{item_name: "Casual shirt", base_color: "black", price: 20}
]
bottoms = [
  %{item_name: "Jeans", base_color: "blue", price: 30},
  %{item_name: "Dress trousers", base_color: "black", price: 75}
]
BoutiqueSuggestions.get_combinations(tops, bottoms, maximum_price: 50)
# => [
#      {%{item_name: "Casual shirt", base_color: "black", price: 20},
#       %{item_name: "Jeans", base_color: "blue", price: 30}}
#    ]

Source

Created by

  • @neenjaw

Contributed to by

  • @angelikatyborska
  • @kevpo