Cater Waiter

Cater Waiter

Exercício de aprendizagem

Introdução

Um Set é uma coleção de elementos com as seguintes propriedades:

  • Sem ordem definida.
  • As entradas são únicas, por isso as tentativas de adicionar duplicados são ignoradas silenciosamente.
  • Suporta muitas das operações habituais nos conjuntos matemáticos.

Cria um Set com o construtor Set(), usando qualquer iterador como parâmetro.

julia> s1 = Set(1:4)
Set([4, 2, 3, 1])

Adiciona novos elementos com push!() (tal como acontece com os arrays) e remove-os com delete!().

julia> push!(s1, 5)
Set([5, 4, 2, 3, 1])

# Duplicates are ignored
julia> push!(s1, 3)
Set([5, 4, 2, 3, 1])

julia> delete!(s1, 5)
Set([4, 2, 3, 1])

julia> length(s1)  # length counts entries, despite the non-sequential type
4

Operações com conjuntos

Tal como acontece com vários outros tipos de coleção, verifica se um elemento pertence ao conjunto com o operador in ou ∈ (usa \in e depois a tecla de tabulação para obter o símbolo).

julia> 3 ∈ s1
true

São suportadas as seguintes operações sobre pares de conjuntos (os atalhos para o símbolo do operador são mostrados entre parênteses).

  • union(A, B) ou A ∪ B (\cup): todas as entradas em A ou em B, ou em ambos.
  • intersect(A, B) ou A ∩ B (\cap): todas as entradas comuns a A e a B.
  • setdiff(A, B) (sem símbolo): as entradas que estão em A mas não em B.
  • symdiff(A, B) (sem símbolo): as entradas que estão em A ou em B, mas não em ambos.
  • issubset(A, B) ou A ⊆ B (\subseteq) ou B ⊇ A (\supseteq): true se todas as entradas de A também estiverem em B.
  • issetequal(A, B) (sem símbolo): true se A e B contiverem exatamente as mesmas entradas.
  • isdisjoint(A, B) (sem símbolo): true se A e B não tiverem entradas em comum (ou seja, se a interseção for vazia).
julia> s1 = Set(1:4);
julia> s2 = Set(3:6);
julia> s1 ∪ s2  # union
Set([5, 4, 6, 2, 3, 1])

julia> s1 ∩ s2  # intersect
Set([4, 3])
  
julia> setdiff(s1, s2)
Set([2, 1])

julia> symdiff(s1, s2)
Set([5, 6, 2, 1])
  
julia> s1 ⊇ s2  # issubset
false

Existem também versões mutantes de muitas destas operações, com um ! acrescentado ao nome da função. Consulta o manual para veres a lista completa de funções.

Instruções

Tu e os teus parceiros de negócio gerem uma pequena empresa de catering. Acabaram de aceitar organizar um evento para um clube de culinária local que tem como destaque pratos "favoritos do clube". O clube tem pouca experiência a organizar eventos grandes e precisa de ajuda com a organização, as compras, a preparação e o serviço. Decidiste escrever pequenas funções em Julia para acelerar todo o processo de planeamento.

1. Limpa os ingredientes dos pratos

As receitas do evento foram adicionadas a partir de várias fontes e os seus ingredientes parecem ter entradas duplicadas (ou mais). Não queres acabar por comprar itens a mais! Antes de começarem as compras e a cozinha, a lista de ingredientes de cada prato tem de ser "limpa".

Implementa a função clean_ingredients(dish_name, dish_ingredients) que recebe o nome de um prato e um Vector de ingredientes. Esta função deve devolver um Tuple com o nome do prato como primeiro item, seguido do Set de ingredientes sem duplicados.

julia> clean_ingredients("Punjabi-Style Chole", ["onions", "tomatoes", "ginger paste", "garlic paste", "ginger paste", "vegetable oil", "bay leaves", "cloves", "cardamom", "cilantro", "peppercorns", "cumin powder", "chickpeas", "coriander powder", "red chili powder", "ground turmeric", "garam masala", "chickpeas", "ginger", "cilantro"])
("Punjabi-Style Chole", Set(["garam masala", "bay leaves", "ground turmeric", "ginger", "garlic paste", "peppercorns", "ginger paste", "red chili powder", "cardamom", "chickpeas", "cumin powder", "vegetable oil", "tomatoes", "coriander powder", "onions", "cilantro", "cloves"]))

2. Cocktails e Mocktails

O evento vai incluir cocktails e "mocktails", bebidas mistas sem álcool. Precisas de garantir que as bebidas "mocktail" não têm mesmo álcool e que os cocktails incluem mesmo álcool.

Implementa a função check_drinks(drink_name, drink_ingredients) que recebe o nome de uma bebida e um Vector de ingredientes. A função deve devolver o nome da bebida seguido de "Mocktail" se a bebida não tiver ingredientes alcoólicos, e o nome da bebida seguido de "Cocktail" se a bebida incluir álcool. Para os efeitos deste exercício, os cocktails só incluirão álcool proveniente da constante ALCOHOLS:

julia> check_drinks("Honeydew Cucumber", ["honeydew", "coconut water", "mint leaves", "lime juice", "salt", "english cucumber"])
"Honeydew Cucumber Mocktail"

julia> check_drinks("Shirley Tonic", ["cinnamon stick", "scotch", "whole cloves", "ginger", "pomegranate juice", "sugar", "club soda"])
"Shirley Tonic Cocktail"

3. Categoriza os pratos

A lista de convidados inclui pessoas com necessidades alimentares diferentes, e a tua equipa terá de separar os pratos em Vegan, Vegetarian, Paleo, Keto e Omnivore.

Implementa a função categorize_dish(dish_name, dish_ingredients) que recebe o nome de um prato e um set dos ingredientes desse prato. A função deve devolver uma String com o formato dish name: CATEGORY (a que categoria de refeição pertence o prato). Todos os pratos "encaixam" numa das categorias: VEGAN, VEGETARIAN, PALEO, KETO ou OMNIVORE.

julia> categorize_dish("Sticky Lemon Tofu", Set(["tofu", "soy sauce", "salt", "black pepper", "cornstarch", "vegetable oil", "garlic", "ginger", "water", "vegetable stock", "lemon juice", "lemon zest", "sugar"]))
"Sticky Lemon Tofu: VEGAN"

julia> categorize_dish("Shrimp Bacon and Crispy Chickpea Tacos with Salsa de Guacamole", Set(["shrimp", "bacon", "avocado", "chickpeas", "fresh tortillas", "sea salt", "guajillo chile", "slivered almonds", "olive oil", "butter", "black pepper", "garlic", "onion"]))
"Shrimp Bacon and Crispy Chickpea Tacos with Salsa de Guacamole: OMNIVORE"

4. Etiqueta alergénios e alimentos restritos

Alguns convidados têm alergias e restrições alimentares adicionais. Estes ingredientes têm de ser etiquetados/anotados para cada prato, para que não causem problemas.

Implementa a função tag_special_ingredients(dish) que recebe um Tuple com o nome do prato na primeira posição e um Vector ou Set de ingredientes desse prato na segunda posição. Devolve o nome do prato seguido do Set de ingredientes que precisam de uma nota especial na descrição do prato. Os ingredientes de um prato dentro de um Vector podem ou não ter duplicados. Para os efeitos deste exercício, todos os alergénios ou ingredientes especiais que precisam de ser etiquetados estão na constante SPECIAL_INGREDIENTS.

julia> tag_special_ingredients(("Ginger Glazed Tofu Cutlets", ["tofu", "soy sauce", "ginger", "corn starch", "garlic", "brown sugar", "sesame seeds", "lemon juice"]))
("Ginger Glazed Tofu Cutlets", Set(["garlic","soy sauce","tofu"]))

julia> tag_special_ingredients(("Arugula and Roasted Pork Salad", ["pork tenderloin", "arugula", "pears", "blue cheese", "pine nuts", "balsamic vinegar", "onions", "black pepper"
]))
("Arugula and Roasted Pork Salad", Set(["pork tenderloin", "blue cheese", "pine nuts", "onions"]))

5. Compila uma "lista mestra" de ingredientes

Em preparação para encomendar e fazer compras, vais precisar de compilar uma "lista mestra" de ingredientes para tudo o que está no menu (quantidades a preencher mais tarde).

Implementa a função compile_ingredients(dishes) que recebe um Vector de pratos e devolve um conjunto com todos os ingredientes de todos os pratos listados. Cada prato individual é representado pelo seu Set de ingredientes.

julia> dishes = [Set(["tofu", "soy sauce", "ginger", "corn starch", "garlic", "brown sugar", "sesame seeds", "lemon juice"]), Set(["pork tenderloin", "arugula", "pears", "blue cheese", "pine nuts","balsamic vinegar", "onions", "black pepper"]), Set(["honeydew", "coconut water", "mint leaves", "lime juice", "salt", "english cucumber"])];

julia> compile_ingredients(dishes)
Set(["arugula", "brown sugar", "honeydew", "coconut water", "english cucumber", "balsamic vinegar", "mint leaves", "pears", "pork tenderloin", "ginger", "blue cheese", "soy sauce", "sesame seeds", "black pepper", "garlic", "lime juice", "corn starch", "pine nuts", "lemon juice", "onions", "salt", "tofu"])

6. Retira os aperitivos para servir em tabuleiros

Os anfitriões deram-te uma lista de pratos que gostariam que fossem preparados como aperitivos "de uma dentada" para serem servidos em tabuleiros. Precisas de os retirar da lista principal de pratos que estão a ser preparados em porções maiores.

Implementa a função separate_appetizers(dishes, appetizers) que recebe um Vector de nomes de pratos e um Vector de nomes de aperitivos. A função deve devolver um Vector com a lista de nomes de pratos sem os nomes dos aperitivos. Tanto o Vector dishes como o appetizers podem conter duplicados e podem precisar de ser limpos de duplicados.

julia> dishes = ["Avocado Deviled Eggs","Flank Steak with Chimichurri and Asparagus", "Kingfish Lettuce Cups", "Grilled Flank Steak with Caesar Salad","Vegetarian Khoresh Bademjan","Avocado Deviled Eggs", "Barley Risotto","Kingfish Lettuce Cups"];
          
julia> appetizers = ["Kingfish Lettuce Cups","Avocado Deviled Eggs","Satay Steak Skewers", "Dahi Puri with Black Chickpeas","Avocado Deviled Eggs","Asparagus Puffs", "Asparagus Puffs"];
              
julia> separate_appetizers(dishes, appetizers)
["Vegetarian Khoresh Bademjan", "Barley Risotto", "Flank Steak with Chimichurri and Asparagus", "Grilled Flank Steak with Caesar Salad"]

7. Encontra ingredientes usados numa só receita

Dentro de cada categoria (VEGAN, VEGETARIAN, PALEO, KETO ou OMNIVORE), vais retirar os ingredientes que aparecem em apenas um prato. Estes ingredientes "singleton" serão atribuídos a um comprador especial para garantir que não são esquecidos na correria de fazer tudo o resto.

Implementa a função singleton_ingredients(dishes, intersection) que recebe um Vector de pratos e uma constante CATEGORY_INTERSECTION para a mesma categoria. Cada prato é representado por um Set dos seus ingredientes. Cada CATEGORY_INTERSECTION é um Set de ingredientes que aparecem em mais do que um prato da categoria. Usando operações de conjuntos, a tua função deve devolver um Set de ingredientes "singleton" (ingredientes que aparecem em apenas um prato da categoria).

julia> singleton_ingredients(example_dishes, EXAMPLE_INTERSECTION)
Set(["garlic powder", "sunflower oil", "mixed herbs", "cornstarch", "celeriac", "honey", "mushrooms", "bell pepper", "rosemary", "parsley", "lemon", "yeast", "vegetable oil", "vegetable stock", "silken tofu", "tofu", "cashews", "lemon zest", "smoked tofu", "spaghetti", "ginger", "breadcrumbs", "tomatoes", "barley malt", "red pepper flakes", "oregano", "red onion", "fresh basil"])
Editar via GitHub A ligação abre numa nova janela ou separador
Julia Exercism

Estás pronto para começar Cater Waiter?

Inscreve-te no Exercism para aprenderes e dominares Julia com 35 conceitos128 exercícios, e mentoria humana real, tudo grátis.