Trilhas
/
Elm
Elm
/
Exercícios
/
Artilheiros
Artilheiros

Artilheiros

Exercício de aprendizagem

Introdução

Dicionário

Um Dict no 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 são escritas 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 itens podem ser recuperados usando get. Como uma chave pode ou não estar presente no dicionário, o resultado será envolvido em um Maybe.

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

Os itens podem ser adicionados usando insert. Itens de chaves que já estão 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 itens podem ser atualizados usando update. Se a chave não existir, a função de atualização será 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 itens podem ser removidos usando remove. Se a chave não existir, nenhuma mudança é feita.

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 em um dicionário com fromList.

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

Os itens podem ser convertidos em uma lista usando toList. A lista é ordenada pelas chaves.

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

Vários itens podem ser removidos usando filter.

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

Os itens podem ser transformados usando map.

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

Dicionários podem ser combinados / transformados usando 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/operador que pareça modificar um dicionário (como adicionar um elemento) na verdade retornará um novo dicionário. O desempenho geralmente não é um problema, pois a implementação evita alocações/cópias desnecessárias.

No 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

Sua tarefa é receber uma lista de marcadores de um jogo e contar quantos gols cada jogador marcou.

PlayerName é um alias de tipo para String, para deixar 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, implemente updateGoalCountForPlayer para inicializar ou incrementar a contagem de gols de um jogador. Depois, implemente a função aggregateScorers para contar quantos gols cada jogador marcou, usando updateGoalCountForPlayer. Essa função recebe uma List PlayerName (os nomes dos jogadores que marcaram os gols, que pode conter nomes de jogadores duplicados) e retorna um Dict PlayerName Int contendo todos os jogadores da lista junto com quantos gols eles marcaram.

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

2. Remover jogadores insignificantes

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

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

3. Redefinir a contagem de gols de um jogador

Implemente a função resetPlayerGoalCount para redefinir para zero os gols marcados de um jogador.

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

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

Implemente a função formatPlayer para formatar a contagem de gols de um único jogador como uma string. Se o jogador não existir no dicionário, assuma que a contagem de gols dele é zero.

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

5. Formatar a contagem de gols de todos os jogadores

Implemente a função formatPlayers para formatar a contagem de gols de todos os jogadores como uma string. Os jogadores devem ser ordenados pelo nome.

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

6. Combinar jogos

Implemente a função combineGames para contar o número total de gols 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 O link abre em uma nova janela ou aba
Elm Exercism

Tudo pronto para começar Artilheiros?

Crie sua conta no Exercism para aprender e dominar Elm com 28 conceitos110 exercícios e mentoria humana de verdade, tudo de graça.