Percursos
/
Swift
Swift
/
Exercícios
/
Quadro de Recordes
Quadro de Recordes

Quadro de Recordes

Exercício de aprendizagem

Introdução

Dicionários são um dos principais tipos de coleção do Swift. Um dicionário armazena associações sem ordem entre chaves únicas e os valores correspondentes. Todas as chaves de um dicionário têm de ser do mesmo tipo, e todos os valores também têm de partilhar o mesmo tipo.

Os literais de dicionário escrevem-se como pares key: value separados por vírgulas e entre parênteses retos:

var addresses: Dictionary<String, String> = [
    "The Munsters": "1313 Mockingbird Lane",
    "The Simpsons": "742 Evergreen Terrace",
    "Buffy Summers": "1630 Revello Drive"
]

var sequences: [String: [Int]] = [
    "Euler's totient": [1, 1, 2, 2, 4, 2, 6, 4],
    "Lazy caterer": [1, 2, 4, 7, 11, 16, 22, 29, 37],
    "Carmichael": [561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841]
]

let constants = [
    "pi": 3.14159,
    "e": 2.71828,
    "phi": 1.618033,
    "avogadro": 6.02214076e23
]

Os tipos de dicionário podem escrever-se explicitamente de duas formas: Dictionary<Key, Value> ou a sintaxe abreviada [Key: Value].

Para criar um dicionário vazio, especifica explicitamente os tipos das chaves e dos valores:

var emptyDict1: [Int: Int] = [:]
var emptyDict2 = [Character: String]()
var emptyDict3 = Dictionary<Int, Double>()

Aceder a valores

Podes aceder aos valores com a notação de subscrito: coloca a chave entre parênteses retos a seguir ao nome do dicionário. Como uma chave pode não existir no dicionário, o acesso por subscrito devolve um opcional (Value?). Se a chave estiver presente, o Swift devolve o valor encapsulado; se não estiver, devolve nil:

let munster: String? = addresses["The Munsters"]
// Returns Optional("1313 Mockingbird Lane")

let carmichael = sequences["Carmichael"]
// Returns Optional([561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841])

let planck = constants["planck"]
// Returns nil

Para evitares lidar com opcionais, podes indicar um valor por omissão através do parâmetro default:

let e: Double = constants["e", default: 0]
// Returns 2.71828

let hoagie: [Int] = sequences["Hoagie", default: []]
// Returns []

let betty = addresses["Betty Cooper", default: "Address unknown"]
// Returns "Address unknown"

Modificar dicionários

Nos dicionários mutáveis declarados com var, podes adicionar ou atualizar pares chave-valor através de atribuição por subscrito:

sequences["Euler's totient"]?.append(contentsOf: [6, 4])
// sequences["Euler's totient"] is now [1, 1, 2, 2, 4, 2, 6, 4, 6, 4]

addresses["Betty Cooper"] = "111 Queens Ave."
addresses["Betty Cooper", default: "Address unknown"]
// Returns "111 Queens Ave."

constants["Gelfond's"] = 23.140692
// Compiler error: Cannot assign through subscript: 'constants' is a 'let' constant

Iterar sobre um dicionário

Podes iterar sobre cada par chave-valor de um dicionário com um ciclo for-in. Cada item é fornecido como um tuplo (key, value):

for (name, address) in addresses {
    print("\(name) lives at \(address)")
}

Ordenar dicionários

Como os dicionários não têm ordem, ordená-los produz um array de pares chave-valor. Podes passar um closure ao método sorted(by:) que compara dois tuplos (key, value) e devolve true se o primeiro tuplo dever aparecer antes do segundo:

func sortByNameLengthThenValue(_ lhs: (key: String, value: Double), _ rhs: (key: String, value: Double)) -> Bool {
    let left = lhs.value + Double(lhs.key.count)
    let right = rhs.value + Double(rhs.key.count)
    return left < right
}

let sortedConstants = constants.sorted(by: sortByNameLengthThenValue)

Instruções

Neste exercício, vais implementar uma forma de acompanhar as pontuações máximas do jogo mais popular do salão de jogos da tua zona.

Tens 7 funções para implementar, todas relacionadas com devolver e manipular um dicionário de dados de pontuações máximas.

1. Define um novo dicionário de pontuações máximas

Cria uma função newScoreBoard() que não recebe parâmetros e devolve um novo dicionário de pontuações máximas que usa valores do tipo String para as chaves e valores do tipo Int para os valores.

2. Adiciona jogadores ao dicionário de pontuações máximas

Para adicionares um jogador ao dicionário de pontuações máximas, define addPlayer(_:_:_:), que é uma função que recebe 3 parâmetros:

  • O primeiro parâmetro é o dicionário de pontuações. Este deve ser um parâmetro de entrada e saída.
  • O segundo parâmetro é o nome de um jogador, como string.
  • O terceiro parâmetro é a pontuação, como número inteiro. O parâmetro é opcional, por isso implementa o terceiro parâmetro com um valor predefinido de 0.
var highScores = newScoreBoard()
addPlayer(&highScores, "Dave Thomas")
// Returns ["Dave Thomas": 0]
addPlayer(&highScores, "José Valim", 486_373)
// Returns ["Dave Thomas": 0, "José Valim": 486_373]

3. Remove jogadores do dicionário de pontuações

Para removeres um jogador do dicionário de pontuações máximas, define removePlayer(_:_:), que recebe 2 parâmetros:

  • O primeiro parâmetro é o dicionário de pontuações. Este deve ser um parâmetro de entrada e saída.
  • O segundo parâmetro é o nome do jogador, como string.

Esta função deve remover o jogador do dicionário, se ele lá estiver, e não fazer nada caso contrário.

var highScores = ["Dave Thomas": 0, "José Valim": 486_373]
removePlayer(&highScores, "Dave Thomas")
// Returns ["José Valim": 486_373]
removePlayer(&highScores, "Rose Fanaras")
// Returns ["José Valim": 486_373]

4. Reinicia a pontuação de um jogador

Para reiniciares a pontuação de um jogador, define resetPlayer(_:_:), que recebe 2 parâmetros:

  • O primeiro parâmetro é o dicionário de pontuações. Este deve ser um parâmetro de entrada e saída.
  • O segundo parâmetro é o nome do jogador cuja pontuação queres reiniciar, como string.

A função coloca a pontuação do jogador a 0. Se o jogador não estiver no dicionário, não deve acontecer nada.

var highScores = ["Dave Thomas": 486_373, "José Valim": 10]
resetScore(&highScores, "Dave Thomas")
// Returns ["Dave Thomas": 0, "José Valim": 10]

5. Atualiza a pontuação de um jogador

Para atualizares a pontuação de um jogador somando-a à pontuação anterior, define updateScore, que recebe 3 parâmetros:

  • O primeiro parâmetro é o dicionário de pontuações. Este deve ser um parâmetro de entrada e saída.
  • O segundo parâmetro é o nome do jogador cuja pontuação queres atualizar, como string.
  • O terceiro parâmetro é a pontuação que queres somar à pontuação máxima guardada.
var highScores = ["Dave Thomas": 0, "José Valim": 486_373]
addPlayer(&highScores, "Freyja Ćirić", 12_771_008)
updateScore(&highScores, "Freyja Ćirić", 73)
// Returns ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_081]

6. Obtém uma lista de jogadores com as pontuações ordenadas pelo nome do jogador

Define a função orderByPlayers, que recebe 1 parâmetro:

  • O primeiro parâmetro é o dicionário de pontuações.

A função devolve um array de tuplos (String, Int) com os jogadores e as respetivas pontuações máximas, ordenados por ordem crescente do nome do jogador.

var highScores = ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_091]
orderByPlayers(highScores)
// Returns [("Dave Thomas", 0), ("Freyja Ćirić", 12_771_091), ("José Valim", 486_373)]

7. Obtém uma lista de jogadores ordenada pela pontuação, por ordem decrescente

Para obteres uma lista de jogadores ordenada pelas pontuações por ordem decrescente, define orderByScores, que recebe 1 parâmetro:

  • O primeiro parâmetro é o dicionário de pontuações.

A função devolve um array de tuplos (String, Int) com os jogadores e as respetivas pontuações máximas, ordenados por ordem decrescente da pontuação do jogador.

var highScores = ["Dave Thomas": 0, "José Valim": 486_373, "Freyja Ćirić": 12_771_091]
orderByScores(highScores)
// Returns [("Freyja Ćirić", 12_771_091), ("José Valim", 486_373), ("Dave Thomas", 0)]
Editar via GitHub A ligação abre numa nova janela ou separador
Swift Exercism

Estás pronto para começar Quadro de Recordes?

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