Tracks
/
Elm
Elm
/
Ejercicios
/
Máximos goleadores
Máximos goleadores

Máximos goleadores

Ejercicio de aprendizaje

Introducción

Dict

Un Dict en Elm es un diccionario inmutable de cero o más pares clave-valor.

Los diccionarios se manipulan con funciones y operadores definidos en el módulo Dict.

Las anotaciones de tipo para diccionarios se escriben de la siguiente manera

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

Los diccionarios se pueden crear de la siguiente manera:

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

Los elementos se pueden obtener usando get. Como una clave puede estar o no presente en el diccionario, el resultado se envuelve en un Maybe.

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

Los elementos se pueden agregar usando insert. Los elementos para claves que ya están en el diccionario se reemplazan.

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 ) ]

Los elementos se pueden actualizar usando update. Si la clave no existe, la función de actualización se llamará con 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" ) ]

Los elementos se pueden eliminar usando remove. Si la clave no existe, no se hace ningún cambio.

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

Una lista de pares clave-valor se puede convertir en un diccionario con fromList.

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

Los elementos se pueden convertir en una lista usando toList. La lista está ordenada por las claves.

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

Se pueden eliminar varios elementos usando filter.

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

Los elementos se pueden transformar usando map.

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

Los diccionarios se pueden combinar o transformar 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 ) ]

Cualquier función u operador que parezca modificar un diccionario (como agregar un elemento), en realidad devolverá un nuevo diccionario. El rendimiento generalmente no es un problema, ya que la implementación evita asignaciones y copias innecesarias.

En Elm, generalmente es mejor usar abstracciones de más alto nivel, como Dict.map, Dict.filter y Dict.merge, en lugar de abstracciones de más bajo nivel como Dict.get y Dict.remove, aunque, por supuesto, depende del contexto.

Instrucciones

Tu tarea es tomar una lista de anotadores de un partido y contar cuántos goles anotó cada jugador.

PlayerName es un alias de tipo para String, para que el código sea más fácil de leer y para distinguir este uso de String de otros usos de String.

1. Acumula los anotadores

Primero implementa updateGoalCountForPlayer para inicializar o incrementar el recuento de goles de un jugador. Luego implementa la función aggregateScorers para contar cuántos goles anotó cada jugador, usando updateGoalCountForPlayer. Esta función recibe una List PlayerName (los nombres de los jugadores que anotaron los goles, que puede contener nombres de jugadores duplicados) y devuelve un Dict PlayerName Int con todos los jugadores de la lista junto con cuántos goles anotaron.

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

2. Elimina los jugadores insignificantes

Implementa la función removeInsignificantPlayers para filtrar los jugadores que hayan anotado menos goles que el umbral.

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

3. Restablece el recuento de goles de un jugador

Implementa la función resetPlayerGoalCount para restablecer a cero los goles anotados por un jugador.

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

4. Formatea el recuento de goles de un solo jugador

Implementa la función formatPlayer para formatear como una cadena el recuento de goles de un solo jugador. Si el jugador no existe en el diccionario, asume que su recuento de goles es cero.

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

5. Formatea el recuento de goles de todos los jugadores

Implementa la función formatPlayers para formatear como una cadena el recuento de goles de todos los jugadores. Los jugadores deben estar ordenados por su nombre.

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

6. Combina los partidos

Implementa la función combineGames, que cuenta el total de goles que anotó cada jugador en ambos partidos.

combine Games
  (Dict.fromList [ ( "Betty", 2 ), ( "Cedd", 1 ) ] )
  (Dict.fromList [ ( "Betty", 2 ), ( "Mario", 3 ) ] )
--> Dict.fromList [ ( "Betty", 4 ), ( "Cedd", 1 ), ( "Mario", 3 ) ]
Editar en GitHub El enlace se abre en una ventana o una pestaña nuevas
Elm Exercism

¿Todo listo para empezar Máximos goleadores?

Regístrate en Exercism para aprender y dominar Elm con 28 conceptos110 ejercicios y mentoría humana real, todo gratis.