Compare commits

..

2 Commits

Author SHA1 Message Date
Alexander Heldt
d8e3cea890 high-score-board v2 2025-11-08 15:31:38 +01:00
Alexander Heldt
84098e7db9 high-score-board 2025-11-08 15:30:12 +01:00
10 changed files with 369 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
{
"authors": [
"lpil"
],
"files": {
"solution": [
"src/high_score_board.gleam"
],
"test": [
"test/high_score_board_test.gleam"
],
"exemplar": [
".meta/example.gleam"
],
"invalidator": [
"gleam.toml",
"manifest.toml"
]
},
"forked_from": [
"javascript/high-score-board"
],
"blurb": "Practice Gleam dicts by tracking high scores of an arcade game."
}

View File

@@ -0,0 +1 @@
{"track":"gleam","exercise":"high-score-board","id":"51923a5987d74c51bcec5743a623c549","url":"https://exercism.org/tracks/gleam/exercises/high-score-board","handle":"fw353qwgs","is_requester":true,"auto_approve":false}

4
high-score-board/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.beam
*.ez
build
erl_crash.dump

32
high-score-board/HELP.md Normal file
View File

@@ -0,0 +1,32 @@
# Help
## Running the tests
To run the tests, run the command `gleam test` from within the exercise directory.
## Submitting your solution
You can submit your solution using the `exercism submit src/high_score_board.gleam` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Gleam track's documentation](https://exercism.org/docs/tracks/gleam)
- The [Gleam track's programming category on the forum](https://forum.exercism.org/c/programming/gleam)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [gleam.run](https://gleam.run/documentation/) is the gleam official documentation.
- [Discord](https://discord.gg/Fm8Pwmy) is the discord channel.
- [StackOverflow](https://stackoverflow.com/questions/tagged/gleam) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.

29
high-score-board/HINTS.md Normal file
View File

@@ -0,0 +1,29 @@
# Hints
## 1. Create a new high score board
- The [`dict.new`][new] and [`dict.from_list`][from_list] functions can be used to create a new dict.
## 2. Add players to a score board
- The [`dict.insert`][insert] function can be used to add a new key-value pair to a dict.
## 3. Remove players from a score board
- The [`dict.delete`][delete] function can be used to remove a key-value pair from a dict.
## 4. Increase a player's score
- The [`dict.get`][get] function can be used to get the value for a key in a dict.
- The [`dict.insert`][insert] function can be used to overwrite an existing key-value pair in a dict.
## 5. Apply Monday bonus points
- The [`dict.map_values`][map_values] function can be used to modify all the values in a dict.
[new]: https://hexdocs.pm/gleam_stdlib/gleam/dict.html#new
[get]: https://hexdocs.pm/gleam_stdlib/gleam/dict.html#get
[insert]: https://hexdocs.pm/gleam_stdlib/gleam/dict.html#insert
[delete]: https://hexdocs.pm/gleam_stdlib/gleam/dict.html#delete
[from_list]: https://hexdocs.pm/gleam_stdlib/gleam/dict.html#from_list
[map_values]: https://hexdocs.pm/gleam_stdlib/gleam/dict.html#map_values

123
high-score-board/README.md Normal file
View File

@@ -0,0 +1,123 @@
# High Score Board
Welcome to High Score Board on Exercism's Gleam Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
## Introduction
## Type Aliases
### Type aliases
A type alias can be used in Gleam to give a convenient name for an existing type that would be otherwise cumbersome to write.
```gleam
pub type Headers =
List(#(String, String))
pub fn html_headers() -> Headers {
[
#("content-type", "text/html"),
#("x-frame-options", "DENY"),
]
}
```
When written with `pub type` the alias can be used outside of the module it is defined in. If `pub` is omitted then the alias is private and cannot be referenced in other modules.
## Dicts
Dicts in Gleam are the data structure for storing information in key-value pairs. In other languages, these might also be known as associative arrays, hashes, or dictionaries.
Any type can be used for the keys and values in a dict, and they do not guarantee the order of their entries when accessed or returned.
### Working with dicts
Dicts are created and manipulated using functions from the `gleam/dict` module.
```gleam
// Create an empty dict
let dict1 = dict.new()
// Create a dict with some values
let dict2 = dict.from_list([
#("name", "Gleam"),
#("colour", "Pink"),
])
// Add a value to a dict
let dict3 = dict.insert(dict2, "website", "https://gleam.run")
// Get a value from a dict
let name = dict.get(dict3, "name")
// -> Ok("Gleam")
```
## Instructions
In this exercise, you are implementing a way to keep track of the high scores for the most popular game in your local arcade hall.
You have 5 functions to implement, mostly related to manipulating an object that holds high scores.
## 1. Create a new high score board
Create a function `create_score_board` that returns a dict that serves as a high score board.
The keys of this object will be the names of the players, the values will be their scores.
For testing purposes, you want to directly include one entry in the object.
This initial entry should consist of `"The Best Ever"` as player name and `1_000_000` as score.
```gleam
create_score_board()
// returns an object with one initial entry
```
## 2. Add players to a score board
To add a player to the high score board, define the function `add_player`.
It accepts 3 parameters:
- The first parameter is an existing score board dict.
- The second parameter is the name of a player as a string.
- The third parameter is the score as an int.
The function returns a dict with the new player and score added.
## 3. Remove players from a score board
If players violate the rules of the arcade hall, they are manually removed from the high score board.
Define `remove_player` which takes 2 parameters:
- The first parameter is an existing score board dict.
- The second parameter is the name of the player as a string.
This function should return the dict without the player that was removed.
If the player was not on the board in the first place, nothing should happen to the board, it should be returned as is.
## 4. Increase a player's score
If a player finishes another game at the arcade hall, a certain amount of points will be added to the previous score on the board.
Implement `update_score`, which takes 3 parameters:
- The first parameter is an existing score board dict.
- The second parameter is the name of the player whose score should be increased.
- The third parameter is the score that you wish to **add** to the stored high score.
The function should return a dict with the updated score.
If the player was not on the board in the first place, nothing should happen to the board, it should be returned as is.
## 5. Apply Monday bonus points
The arcade hall keeps a separate score board on Mondays.
At the end of the day, each player on that board gets 100 additional points.
Implement the function `apply_monday_bonus` that accepts a score board.
The function returns a dict with the bonus points added for each player that is listed on that board.
## Source
### Created by
- @lpil

View File

@@ -0,0 +1,14 @@
name = "high_score_board"
version = "0.1.0"
[dependencies]
gleam_otp = "~> 0.7 or ~> 1.0"
gleam_stdlib = ">= 0.54.0 or ~> 1.0"
simplifile = "~> 1.0"
gleam_erlang = ">= 0.25.0 and < 1.0.0"
gleam_yielder = ">= 1.1.0 and < 2.0.0"
gleam_regexp = ">= 1.1.0 and < 2.0.0"
gleam_deque = ">= 1.0.0 and < 2.0.0"
[dev-dependencies]
exercism_test_runner = "~> 1.9"

View File

@@ -0,0 +1,31 @@
# This file was generated by Gleam
# You typically do not need to edit this file
packages = [
{ name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
{ name = "exercism_test_runner", version = "1.9.0", build_tools = ["gleam"], requirements = ["argv", "gap", "glance", "gleam_community_ansi", "gleam_erlang", "gleam_json", "gleam_stdlib", "simplifile"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "0B17BB25F2FF1E60266467C24FE0CA04005410306AA05E9A4B41B1852D72865C" },
{ name = "filepath", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "67A6D15FB39EEB69DD31F8C145BB5A421790581BD6AA14B33D64D5A55DBD6587" },
{ name = "gap", version = "1.1.3", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib"], otp_app = "gap", source = "hex", outer_checksum = "6EF5E3B523FDFBC317E9EA28D5163EE04744A97C007106F90207569789612291" },
{ name = "glance", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "glexer"], otp_app = "glance", source = "hex", outer_checksum = "E155BA1A787FD11827048355021C0390D2FE9A518485526F631A9D472858CC6D" },
{ name = "gleam_community_ansi", version = "1.4.3", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_regexp", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "8A62AE9CC6EA65BEA630D95016D6C07E4F9973565FA3D0DE68DC4200D8E0DD27" },
{ name = "gleam_community_colour", version = "2.0.0", build_tools = ["gleam"], requirements = ["gleam_json", "gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "FDD6AC62C6EC8506C005949A4FCEF032038191D5EAAEC3C9A203CD53AE956ACA" },
{ name = "gleam_deque", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_deque", source = "hex", outer_checksum = "64D77068931338CF0D0CB5D37522C3E3CCA7CB7D6C5BACB41648B519CC0133C7" },
{ name = "gleam_erlang", version = "0.34.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "0C38F2A128BAA0CEF17C3000BD2097EB80634E239CE31A86400C4416A5D0FDCC" },
{ name = "gleam_json", version = "2.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_json", source = "hex", outer_checksum = "C55C5C2B318533A8072D221C5E06E5A75711C129E420DD1CE463342106012E5D" },
{ name = "gleam_otp", version = "0.16.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "50DA1539FC8E8FA09924EB36A67A2BBB0AD6B27BCDED5A7EF627057CF69D035E" },
{ name = "gleam_regexp", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "7F5E0C0BBEB3C58E57C9CB05FA9002F970C85AD4A63BA1E55CBCB35C15809179" },
{ name = "gleam_stdlib", version = "0.55.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "32D8F4AE03771516950047813A9E359249BD9FBA5C33463FDB7B953D6F8E896B" },
{ name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" },
{ name = "glexer", version = "2.2.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glexer", source = "hex", outer_checksum = "5C235CBDF4DA5203AD5EAB1D6D8B456ED8162C5424FE2309CFFB7EF438B7C269" },
{ name = "simplifile", version = "1.7.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "1D5DFA3A2F9319EC85825F6ED88B8E449F381B0D55A62F5E61424E748E7DDEB0" },
]
[requirements]
exercism_test_runner = { version = "~> 1.9" }
gleam_deque = { version = ">= 1.0.0 and < 2.0.0" }
gleam_erlang = { version = ">= 0.25.0 and < 1.0.0" }
gleam_otp = { version = "~> 0.7 or ~> 1.0" }
gleam_regexp = { version = ">= 1.1.0 and < 2.0.0" }
gleam_stdlib = { version = ">= 0.54.0 or ~> 1.0" }
gleam_yielder = { version = ">= 1.1.0 and < 2.0.0" }
simplifile = { version = "~> 1.0" }

View File

@@ -0,0 +1,35 @@
import gleam/dict.{type Dict}
pub type ScoreBoard =
Dict(String, Int)
pub fn create_score_board() -> ScoreBoard {
dict.from_list([#("The Best Ever", 1_000_000)])
}
pub fn add_player(
score_board: ScoreBoard,
player: String,
score: Int,
) -> ScoreBoard {
dict.insert(score_board, player, score)
}
pub fn remove_player(score_board: ScoreBoard, player: String) -> ScoreBoard {
dict.delete(score_board, player)
}
pub fn update_score(
score_board: ScoreBoard,
player: String,
points: Int,
) -> ScoreBoard {
case dict.get(score_board, player) {
Error(_) -> score_board
Ok(score) -> dict.insert(score_board, player, score + points)
}
}
pub fn apply_monday_bonus(score_board: ScoreBoard) -> ScoreBoard {
dict.map_values(score_board, fn(_, score) { score + 100 })
}

View File

@@ -0,0 +1,76 @@
import exercism/should
import exercism/test_runner
import gleam/dict
import high_score_board
pub fn main() {
test_runner.main()
}
pub fn create_score_board_test() {
high_score_board.create_score_board()
|> should.equal(dict.from_list([#("The Best Ever", 1_000_000)]))
}
pub fn add_player_board_test() {
[#("Amil Pastorius", 99_373), #("Min-seo Shin", 0)]
|> dict.from_list
|> high_score_board.add_player("Jessie Johnson", 1337)
|> should.equal(
dict.from_list([
#("Amil Pastorius", 99_373),
#("Min-seo Shin", 0),
#("Jessie Johnson", 1337),
]),
)
}
pub fn remove_player_test() {
[#("Amil Pastorius", 99_373), #("Min-seo Shin", 0), #("Jesse Johnson", 1337)]
|> dict.from_list
|> high_score_board.remove_player("Jesse Johnson")
|> should.equal(
dict.from_list([#("Amil Pastorius", 99_373), #("Min-seo Shin", 0)]),
)
}
pub fn remove_player_unknown_test() {
let board =
dict.from_list([
#("Amil Pastorius", 99_373),
#("Min-seo Shin", 0),
#("Jesse Johnson", 1337),
])
board
|> high_score_board.remove_player("Bruno Santangelo")
|> should.equal(board)
}
pub fn update_score_test() {
[#("Amil Pastorius", 99_373), #("Min-seo Shin", 0), #("Jesse Johnson", 1337)]
|> dict.from_list
|> high_score_board.update_score("Min-seo Shin", 1999)
|> high_score_board.update_score("Jesse Johnson", 1337)
|> high_score_board.update_score("Unknown player", 1)
|> should.equal(
dict.from_list([
#("Amil Pastorius", 99_373),
#("Min-seo Shin", 1999),
#("Jesse Johnson", 2674),
]),
)
}
pub fn apply_monday_bonus_test() {
[#("Amil Pastorius", 345), #("Min-seo Shin", 19), #("Jesse Johnson", 122)]
|> dict.from_list
|> high_score_board.apply_monday_bonus
|> should.equal(
dict.from_list([
#("Amil Pastorius", 445),
#("Min-seo Shin", 119),
#("Jesse Johnson", 222),
]),
)
}