Percursos
/
Elm
Elm
/
Exercícios
/
Melhores marcadores
Melhores marcadores

Melhores marcadores

Exercício de aprendizagem

Introdução

Dict

Um Dict em Elm é um dicionário imutável de zero ou mais pares chave-valor.

Os dicionários são manipulados por funções e operadores definidos no módulo Dict.

As anotações de tipo para dicionários escrevem-se da seguinte forma:

Dict String (List Int) --> a dict with String keys and List Int values
Dict Int String --> a dict with Int keys and String values

Os dicionários podem ser criados da seguinte forma:

empty : Dict Int String
empty = Dict.empty

singleValue = Dict.singleton 5 "Value for key 5" --> Dict Int String

twoValues = Dict.fromList [ ( "Alice", 0 ), ( "Bob", 1 ) ] --> Dict String Int

Os elementos podem ser obtidos com o get. Como uma chave pode estar ou não presente no dicionário, o resultado vem envolvido num Maybe.

alice = Dict.fromList [ ( 0, "Alice" ) ]
keyExists = Dict.get 0 alice --> Just "Alice"
keyNotPresent = Dict.get 1 alice --> Nothing

Os elementos podem ser adicionados com o insert. Os elementos correspondentes a chaves que já existem no dicionário são substituídos.

alice = Dict.fromList [ ( "Alice", 0 ) ]
aliceAndBob = Dict.insert "Bob" 1 alice  --> Dict.fromList [ ( "Alice", 0 ), ( "Bob", 1 ) ]
aliceAndAlice = Dict.insert "Alice" 1 alice  --> Dict.fromList [ ( "Alice", 1 ) ]

Os elementos podem ser atualizados com o update. Se a chave não existir, a função de atualização é chamada com Nothing.

alice = Dict.fromList [ ( 0, "Alice" ) ]
aliceUpperCase = Dict.update 0 (Maybe.map String.toUpper) alice --> Dict.fromList [ ( 0, "ALICE" ) ]
aliceNoCase = Dict.update 0 (\_ -> Nothing) alice --> Dict.empty
bobUpperCase = Dict.update 1 (\_ -> Just "BOB") alice --> Dict.fromList [ ( 0, "Alice" ), ( 1, "BOB" ) ]
bobNoCase = Dict.update 1 (\_ -> Nothing) alice --> Dict.fromList [ ( 0, "Alice" ) ]

Os elementos podem ser removidos com o remove. Se a chave não existir, nada é alterado.

alice = Dict.fromList [ ( 0, "Alice" ) ]
stillAlice = Dict.remove 1 --> ( 0, "Alice" )
empty = Dict.remove 0 alice --> Dict.empty

Uma lista de pares chave-valor pode ser convertida num dicionário com o fromList.

alice = Dict.fromList [ ( 0, "Bob" ), ( 0, "Alice" ) ]
--> True Dict.fromList [ ( 0, "Alice" ) ]

Os elementos podem ser convertidos numa lista com o toList. A lista fica ordenada pelas chaves.

aliceAndBob = Dict.fromList [ ( 1, "Alice" ), ( 0, "Bob" ) ]
bobAndAlice = Dict.toList aliceAndBob
--> [ ( 0, "Bob" ), ( 1, "Alice" ) ]

Vários elementos podem ser removidos com o filter.

aliceAndBob = Dict.fromList [ ( "Alice", 1 ), ( "Bob", 0 ) ]
bob = Dict.filter (\name count -> name == "Bob") aliceAndBob --> Dict.fromList [ ( "Bob", 0 ) ]

Os elementos podem ser transformados com o map.

alice = Dict.fromList [ ( "Alice", 0 ) ]
empty = Dict.map (\player count -> count + 1) alice --> Dict.fromList [ ( "Alice", 1 ) ]

Os dicionários podem ser combinados e transformados com o merge.

aliceAndBob = Dict.fromList [ ( "Alice", 1 ), ( "Bob", 1 ) ]
bobAndCedd = Dict.fromList [ ( "Bob", 1 ), ( "Cedd", 1 ) ]
firstDictCountsDouble = Dict.merge
        -- when only in aliceAndBob
        (\name count mergedCounts -> Dict.insert name (2 * count) mergedCounts)
        -- when in aliceAndBob and bobAndCedd
        (\name aliceAndBobCount bobAndCeddCount mergedCounts -> Dict.insert name (2 * aliceAndBobCount + bobAndCeddCount) mergedCounts)
        -- when only in bobAndCedd
        (\name count mergedCounts -> Dict.insert name count mergedCounts)
        -- the two dicts to merge
        aliceAndBob
        bobAndCedd
        -- the initial state of the merge
        Dict.empty
--> Dict.fromList [ ( "Alice", 2 ), ( "Bob", 3 ), ( "Cedd", 1 ) ]

Qualquer função ou operador que pareça modificar um dicionário (como adicionar um elemento) devolve, na verdade, um novo dicionário. Normalmente o desempenho não é problema, porque a implementação evita alocações e cópias desnecessárias.

Em Elm, geralmente é melhor usar abstrações de nível mais alto, como Dict.map, Dict.filter e Dict.merge, em vez de abstrações de nível mais baixo, como Dict.get e Dict.remove, embora isso dependa, claro, do contexto.

Instruções

A tua tarefa é pegar numa lista de marcadores de um jogo e contar quantos golos cada jogador marcou.

PlayerName é um alias de tipo para String, para tornar o código mais fácil de ler e para distinguir este uso de String de outros usos de String.

1. Agregar os marcadores

Primeiro, implementa updateGoalCountForPlayer para inicializar ou incrementar a contagem de golos de um jogador. Depois, implementa a função aggregateScorers para contar quantos golos cada jogador marcou, utilizando updateGoalCountForPlayer. Esta função recebe uma List PlayerName (os nomes dos jogadores que marcaram os golos, que pode conter nomes de jogadores repetidos) e devolve um Dict PlayerName Int com todos os jogadores da lista e quantos golos marcaram.

aggregateScorers [ "Betty", "Cedd", "Betty" ]
--> Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ]

2. Remover os jogadores irrelevantes

Implementa a função removeInsignificantPlayers para filtrar os jogadores que marcaram menos golos do que o limite.

removeInsignificantPlayers 2 (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> Dict.fromList [ ( "Betty", 2 ) ]

3. Reiniciar a contagem de golos de um jogador

Implementa a função resetPlayerGoalCount para reiniciar a zero os golos marcados por um jogador.

resetPlayerGoalCount "Cedd" (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 0 ) ]

4. Formatar a contagem de golos de um único jogador

Implementa a função formatPlayer para formatar a contagem de golos de um único jogador como uma string. Se o jogador não existir no dicionário, assume que tem uma contagem de golos de zero.

formatPlayer "Betty" (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> "Betty: 2"

5. Formatar a contagem de golos de todos os jogadores

Implementa a função formatPlayers para formatar a contagem de golos de todos os jogadores como uma string. Os jogadores devem ser ordenados por nome de jogador.

formatPlayers (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
--> "Betty: 2, Cedd: 1"

6. Combinar jogos

Implementa a função combineGames, contando o número total de golos que cada jogador marcou nos dois jogos.

combine Games
  (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
  (Dict.fromList [ ( "Betty", 2 ), ( "Mario", 3 ) ] )
--> Dict.fromList [ ( "Betty", 4 ), ( "Cedd", 1 ), ( "Mario", 3 ) ]
Editar via GitHub A ligação abre numa nova janela ou separador
Elm Exercism

Estás pronto para começar Melhores marcadores?

Inscreve-te no Exercism para aprenderes e dominares Elm com 28 conceitos110 exercícios, e mentoria humana real, tudo grátis.