Trilhas
/
Swift
Swift
/
Exercícios
/
Mixologista Especialista
Mixologista Especialista

Mixologista Especialista

Exercício de aprendizagem

Introdução

Switch

Uma instrução switch permite comparar um valor com vários valores possíveis. Ela permite escrever um código mais conciso do que usar várias condicionais else-if. Uma instrução switch começa com a palavra-chave switch seguida do valor a ser comparado. Depois, você pode definir os casos com a palavra-chave case seguida do valor com o qual comparar. A palavra-chave default define o caso padrão quando nenhum dos casos corresponde. Assim como as condicionais else-if, as instruções switch só executam o bloco de código associado ao primeiro caso que corresponder.

switch value {
case 1:
    print("One")
case 2:
    print("Two")
default:
    print("Other")
}

Considere o seguinte exemplo:

if str == "apple" {
    print("Let's bake an apple crumble")
} else if str == "lemon" {
    print("Let's bake a lemon meringue pie!")
} else if str == "peach" {
    print("Let's bake a peach pie!")
} else {
    print("Let's buy ice cream.")
}

Em vez disso, isso poderia ser escrito assim:

switch str {
case "apple":
    print("Let's bake an apple crumble")
case "lemon":
    print("Let's bake a lemon meringue pie!")
case "peach":
    print("Let's bake a peach pie!")
default:
    print("Let's buy ice cream.")
}

Laços while

Um laço while é uma instrução de fluxo de controle que permite executar código enquanto uma determinada condição for verdadeira. O Swift oferece dois tipos de laços while: os laços while e repeat-while. A condição do laço while é avaliada antes de o corpo do laço ser executado; se a condição for falsa, o corpo do laço não será executado nenhuma vez. Os laços while no Swift têm a seguinte estrutura:

while <#condition#> {
  <#code#>
}

Aqui, o laço será executado enquanto o count for maior que 0 e, com isso, imprimirá os números 2, 1 e "Liftoff!".

var count = 2
while count > 0 {
  print("\(count)…")
  count -= 1
}
print("Liftoff!")

// prints:
// 2…
// 1…
// Liftoff!

Um laço repeat-while é semelhante a um laço while, mas a condição é avaliada depois de o corpo do laço ser executado. Isso significa que o corpo do laço sempre será executado pelo menos uma vez, mesmo que a condição seja falsa. Os laços repeat-while no Swift têm a seguinte estrutura:

repeat {
  <#code#>
} while <#condition#>

Aqui, o laço será executado apenas uma vez, já que a condição é falsa. Como é um laço repeat-while, o corpo do laço será executado uma vez antes de a condição ser avaliada.

var count = 2
repeat {
  print("\(count)…")
} while count < 0
print("Liftoff!")

Transferência de controle

O Swift tem um conjunto de instruções que podem ser usadas para alterar o fluxo normal de controle dos laços. Elas são conhecidas como instruções de transferência de controle. Você já viu o return; este conceito vai apresentar outras, que incluem continue, break e rótulos. Não vamos abordar o fallthrough neste conceito, mas você pode ler sobre ele no livro do Swift.

Continue

Às vezes é preciso pular para a próxima iteração de um laço mais cedo, sem concluir o restante das instruções da iteração atual. A palavra-chave continue pode ser usada para isso. Quando o continue é executado, o laço salta para a próxima verificação para ver se a próxima iteração pode rodar, ou seja, o while nos laços while e repeat-while ou a verificação de que há outro elemento na sequência nos laços for-in.

count = 1
while count < 6 {
  count += 1
  if count == 4 { continue }
  print(count)
}

// prints:
// 2
// 3
// 5

Break

Break é usado para sair de um laço mais cedo. Quando o break é executado, o laço é encerrado imediatamente e o programa continua com a primeira instrução depois do laço.

for fruit in ["banana", "grapes", "apple", "strawberry", "kiwi", "lemon"] {
  if !fruit.count.isMultiple(of: 2) { break }
  print(fruit)
}

// prints:
// banana
// grapes

Rótulos

Quando os laços estão aninhados, há momentos em que se pode querer usar break ou continue para sair ou reiniciar os laços externos que contêm o laço em que o break ou continue são usados. Em casos como esses, rótulos podem ser usados para especificar o laço a ser encerrado ou reiniciado. Um laço pode ser rotulado colocando um nome seguido de dois-pontos antes do while, repeat ou for que inicia o laço.

Para ver o efeito de usar rótulos dessa forma, considere o seguinte laço.

outerLoop: for fruit in ["banana", "grapes", "apple", "strawberry", "kiwi", "lemon"] {
  print("\n--- \(fruit) ---")
  for letter in fruit {
    guard letter != "n" else { break outerLoop }
    print(letter)
  }
}

// prints:
// --- banana ---
// b
// a

Instruções

Você é um mixologista especialista, preparando bebidas gostosas para o público aproveitar nas suas noites de balada. Mas você percebeu que poderia facilitar a sua vida escrevendo um pouco de código para ajudar no seu trabalho.

1. Determine quanto tempo leva para preparar um pedido

Bebidas diferentes levam quantidades diferentes de tempo para preparar:

  • "beer", "soda" e "water" levam 0,5 minuto cada.
  • "shot"s levam 1,0 minuto, "mixed drink"s levam 1,5 minutos,
  • "fancy drink"s levam 2,5 minutos,
  • "frozen drink"s levam 3,0 minutos.

Implemente a função timeToPrepare(drinks:), que recebe o argumento drinks, que contém um array de strings representando as bebidas que precisam ser preparadas. A função deve retornar o tempo total que levará para preparar todas as bebidas do array.

timeToPrepare(drinks: ["beer", "frozen drink", "shot"])
// returns 4.5

2. Reponha seu estoque de gomos de limão

Uma das primeiras coisas que você precisa fazer quando começa o seu turno é garantir que o seu potinho de gomos de limão esteja cheio para o turno que vem pela frente. Você vai ter limões de tamanhos diferentes, que rendem quantidades diferentes de gomos: dá para tirar 6 gomos de um limão "small", 8 gomos de um limão "medium" e 10 de um limão "large".

Enquanto você ainda precisar de mais gomos e ainda tiver mais limões para cortar, pegue o primeiro limão do array e subtraia a quantidade adequada de gomos da quantidade de que você precisa. Continue assim até não precisar de mais gomos ou até os limões acabarem.

Implemente a função makeWedges(needed:limes:), que recebe os argumentos needed, que contém o número de gomos que você precisa cortar, e limes, que contém um array de strings representando os tamanhos dos limões que você tem disponíveis para cortar. A função deve retornar o número de limões que você cortou.

makeWedges(needed: 25, limes: ["small", "small", "large", "medium", "small"])
// returns 4

3. Termine o seu turno

Parabéns! Seu longo dia de trabalho está quase no fim e logo você vai para casa trabalhar no seu novo app. Mas você ainda tem uma série de pedidos de bebidas para fazer antes de passar os pedidos para o próximo turno e ir embora.

Enquanto ainda houver tempo no seu turno, você deve fazer o primeiro pedido do array e depois remover esse pedido do array. Depois, você pode subtrair o tempo que levou para preparar esse pedido, de acordo com a sua função timeToPrepare(drinks:), do tempo que resta no seu turno.

Implemente a função finishShift(minutesLeft:remainingOrders:), que recebe o número de minutos restantes no seu turno (garantidamente maior que 0) e um array não vazio de pedidos de bebidas. A função deve retornar o array de pedidos que você ainda não conseguiu fazer antes do fim do seu turno.

finishShift(minutesLeft: 5, remainingOrders: [["beer", "frozen drink", "shot"], ["fancy drink", "soda"], ["beer", "beer", "water"], ["mixed drink", "frozen drink"]])
// returns [["beer", "beer", "water"], ["mixed drink", "frozen drink"]]

4. Acompanhe determinados pedidos

Para garantir que a beer e a soda fiquem frescas, você precisa acompanhar os pedidos delas junto com os horários em que esses pedidos foram feitos.

Implemente a função orderTracker(orders: [(drink: String, time: String)]) -> (beer: (first: String, last: String, total: Int)?, soda: (first: String, last: String, total: Int)?) que, quando recebe uma lista de pedidos e horários, retorna um par de tuplas opcionais contendo os horários do primeiro e do último pedido de beer e de soda, junto com o número total de pedidos de cada uma, e nil se nenhum pedido dessas bebidas foi feito. Você não precisa acompanhar nenhuma outra bebida.

Implemente a função orderTracker(orders:), que recebe um array de tuplas, em que cada tupla contém a bebida pedida e o horário em que o pedido foi feito. A função deve retornar uma tupla contendo o primeiro e o último horário em que a beer foi pedida, o número total de pedidos de beer, o primeiro e o último horário em que a soda foi pedida, e o número total de pedidos de soda. Ela deve ser retornada como uma tupla no formato: (beer: (first: String, last: String, total: Int)?, soda: (first: String, last: String, total: Int)?).

let orders = [
    (drink: "beer", time: "10:01"), (drink: "frozen drink", time: "10:02"),
    (drink: "shot", time: "10:05"), (drink: "fancy drink", time: "10:06"),
    (drink: "soda", time: "10:09"), (drink: "beer", time: "10:15"), (drink: "beer", time: "10:22"),
    (drink: "water", time: "10:26"), (drink: "mixed drink", time: "10:28"),
    (drink: "frozen drink", time: "10:33"),
]

orderTracker(orders: orders)

// returns (beer: (first "10:01", last "10:22", total 3), soda: (first "10:09", last "10:09", total 1))
Editar via GitHub O link abre em uma nova janela ou aba
Swift Exercism

Tudo pronto para começar Mixologista Especialista?

Crie sua conta no Exercism para aprender e dominar Swift com 35 conceitos116 exercícios e mentoria humana de verdade, tudo de graça.