Files
exercism-workspace/bandwagoner/README.md
Alexander Heldt 2ac630dd8c bandwagoner
2025-11-03 21:46:56 +01:00

202 lines
5.9 KiB
Markdown

# Bandwagoner
Welcome to Bandwagoner 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
## Labelled Fields
When a custom type variant holds data it is called a record, and each contained value resides in a _field_.
```gleam
pub type Rectangle {
Rectangle(
Float, // The first field
Float, // The second field
)
}
```
To aid readability Gleam allows fields to be labelled with a name.
```gleam
pub type Rectangle {
Rectangle(
width: Float,
height: Float,
)
}
```
Labels can be used to give arguments in any order to the constructor of a record.
```gleam
let a = Rectangle(height: 10.0, width: 20.0)
let b = Rectangle(width: 20.0, height: 10.0)
a == b
// -> True
```
When a custom type has only one variant then the `.label` accessor syntax can be used to get the fields of a record.
```gleam
let rect = Rectangle(height: 10.0, width: 20.0)
rect.height // -> 10.0
rect.width // -> 20.0
```
The record update syntax can be used when a custom type has a single variant to create a new record from an existing one, but with some of the fields replaced with new values.
```gleam
let rect = Rectangle(height: 10.0, width: 20.0)
let tall_rect = Rectangle(..rect, height: 50.0)
tall_rect.height // -> 50.0
tall_rect.width // -> 20.0
```
Labels can also be used when pattern matching to extract values from records.
```gleam
pub fn is_tall(rect: Rectangle) {
case rect {
Rectangle(height: h, width: _) if h >. 20.0 -> True
_ -> False
}
}
```
If we only want to match on some of the fields we can use the spread operator `..` to ignore any remaining fields.
```gleam
pub fn is_tall(rect: Rectangle) {
case rect {
Rectangle(height: h, ..) if h >. 20.0 -> True
_ -> False
}
}
```
## Instructions
In this exercise you're a big sports fan and you've just discovered a passion for NBA basketball. Being new to NBA basketball, you're doing a deep dive into NBA history, keeping track of teams, coaches, their win/loss stats, and comparing them against each other.
As you don't yet have a favorite team, you'll also be developing an algorithm to figure out whether to root for a particular team.
You have seven tasks to help you develop your proprietary _root-for-a-team_ algorithm.
## 1. Define the model
Define the `Coach` record with the following two fields:
- `name`: the coach's name, of type `String`.
- `former_player`: indicates if the coach was a former player, of type `Bool`.
Define the `Stats` record with the following two fields:
- `wins`: the number of wins, of type `Int`.
- `losses`: the number of losses, of type `Int`.
Define the `Team` record with the following three fields:
- `name`: the team's name, of type `String`.
- `coach`: the team's coach, of type `Coach`.
- `stats`: the team's stats, of type `Stats`.
## 2. Create a team's coach
Implement the `create_coach` function that takes the coach name and its former player status as parameters, and returns its `Coach` record:
```gleam
create_coach("Larry Bird", True)
// -> Coach(name: "Larry Bird", former_player: True)
```
## 3. Create a team's stats
Implement the `create_stats` function that takes the number of wins and the number losses as parameters, and returns its `Stats` record:
```gleam
create_stats(58, 24)
// -> Stats(wins: 58, losses: 24)
```
## 4. Create a team
Implement the `create_team` function that takes the team name, coach and record as parameters, and returns its `Team` record:
```gleam
let coach = create_coach("Larry Bird", True)
let stats = create_stats(58, 24)
create_team("Indiana Pacers", coach, stats)
// -> Team(
// name: "Indiana Pacers",
// coach: Coach(name: "Larry Bird", FormerPlayer = True),
// stats: Stats(wins: 58, losses: 24),
// )
```
## 5. Replace the coach
NBA owners being impatient, you found that bad team results would often lead to the coach being replaced. Implement the `replace_coach` function that takes the team and its new coach as parameters, and returns the team but with the new coach:
```gleam
let coach = create_coach("Larry Bird", True)
let record = create_stats(58, 24)
let team = create_team("Indiana Pacers", coach, record)
let new_coach = create_coach("Isiah Thomas", True)
replace_coach(team, new_coach)
// -> Team(
// name: "Indiana Pacers",
// coach: Coach(name: "Isiah Thomas", FormerPlayer = True),
// stats: Stats(wins: 58, losses: 24),
// )
```
## 6. Check for same team
While digging into stats, you're keeping lists of teams and their records. Sometimes, you get things wrong and there are duplicate entries on your list. Implement the `is_same_team` function that takes two teams and returns `True` if they are the same team, otherwise, return `False`:
```gleam
let pacers_coach = create_coach("Larry Bird", True)
let pacers_stats = create_stats(58, 24)
let pacers_team = create_team("Indiana Pacers", pacers_coach, pacers_stats)
let lakers_coach = create_coach("Del Harris", False)
let lakers_stats = create_stats(61, 21)
let lakers_team = create_team("LA Lakers", lakers_coach, lakers_stats)
is_same_team(pacers_team, lakers_team)
// -> False
```
## 7. Check if you should root for a team
Having looked at many teams and matches, you've come up with an algorithm. If one of the following is True, you root for that team:
- The coach's name is "Gregg Popovich"
- The coach is a former player
- The team's name is the "Chicago Bulls"
- The team has won 60 or more games
- The team has more losses than wins
Implement the `root_for_team` function that takes a team and returns `True` if you should root for that team, otherwise, return `False`:
```gleam
let spurs_coach = create_coach("Gregg Popovich", False)
let spurs_stats = create_stats(56, 26)
let spurs_team = create_team("San Antonio Spurs", spurs_coach, spurs_stats)
root_for_team(spurs_team)
// -> True
```
## Source
### Created by
- @lpil