-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
254399f
commit 685cb90
Showing
8 changed files
with
328 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
*.beam | ||
*.ez | ||
build | ||
erl_crash.dump |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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/bird_count.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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# Hints | ||
|
||
## General | ||
|
||
- Try to split a problem into a base case and a recursive case. For example, let's say you want to count how many cookies are there in the cookie jar with a recursive approach. A base case is an empty jar - it has zero cookies. If the jar is not empty, then the number of cookies in the jar is equal to one cookie plus the number of cookies in the jar after removing one cookie. | ||
|
||
## 1. Check how many birds visited today | ||
|
||
- This task doesn't need recursion. | ||
- Accessing the first element in a list can be done using a case expression. | ||
|
||
## 2. Increment today's count | ||
|
||
- This task doesn't need recursion. | ||
- Accessing the first element in a list and the rest of the list can be done using a case expression. | ||
|
||
## 3. Check if there was a day with no visiting birds | ||
|
||
- Use recursion to iterate over elements in the list until a day with no visiting birds is found. | ||
- The base case is an empty list. | ||
|
||
## 4. Calculate the total number of visiting birds | ||
|
||
- Use recursion to iterate over every element in the list. | ||
- The base case is an empty list. | ||
|
||
## 5. Calculate the number of busy days | ||
|
||
- Use recursion to iterate over every element in the list. | ||
- The base case is an empty list. | ||
- Use a guard for one of the case expression clauses. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# Bird Count | ||
|
||
Welcome to Bird Count 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 | ||
|
||
## Recursion | ||
|
||
The ability for something to be defined in terms of itself is called recursion. In Gleam, recursion is most commonly found in recursive functions, which are functions that call themselves. | ||
|
||
A recursive function needs to have at least one _base case_ and at least one _recursive case_. A _base case_ returns a value without calling the function again. A _recursive case_ calls the function again, modifying the input so that it will at some point match the base case. | ||
|
||
```gleam | ||
pub fn factorial(x: Int) -> Int { | ||
case x { | ||
// Base case | ||
1 -> 1 | ||
// Recursive case | ||
_ -> x * factorial(x - 1) | ||
} | ||
} | ||
``` | ||
|
||
Gleam has no special syntax for looping, so all looping is done with recursion. | ||
|
||
```gleam | ||
pub fn list_length(list: List(String)) -> Int { | ||
case list { | ||
[] -> 0 | ||
[_, ..rest] -> 1 + list_length(rest) | ||
} | ||
} | ||
``` | ||
|
||
Gleam also supports recursive custom types. A recursive custom type has one or more of its variants refer to itself in their contained data. | ||
|
||
```gleam | ||
pub type RussianDoll { | ||
Child // Base case | ||
Mother(RussianDoll) // Recursive case | ||
} | ||
``` | ||
```gleam | ||
let very_big_doll = Mother(Mother(Mother(Child))) | ||
let small_doll = Mother(Child) | ||
``` | ||
|
||
## Instructions | ||
|
||
Izzy is an avid bird watcher that keeps track of how many birds have visited her garden on any given day. | ||
|
||
She's asked you to help bring her bird watching to a new level and implement a few tools that will help her track and process the data. | ||
|
||
You have chosen to store the data as a list of integers. The first number in the list is the number of birds that visited your garden today, the second yesterday, and so on. | ||
|
||
## 1. Check how many birds visited today | ||
|
||
Implement the `bird_count.today` function. It should take a list of daily bird counts and return today's count. If the list is empty, it should return `0`. | ||
|
||
```gleam | ||
bird_count.today([2, 5, 1]) | ||
// -> 2 | ||
``` | ||
|
||
## 2. Increment today's count | ||
|
||
Implement the `bird_count.increment_day_count` function. It should take a list of daily bird counts and increment the today's count by 1. If the list is empty, return `[1]`. | ||
|
||
```gleam | ||
bird_count.increment_day_count([4, 0, 2]) | ||
// -> [5, 0, 2] | ||
``` | ||
|
||
## 3. Check if there was a day with no visiting birds | ||
|
||
Implement the `bird_count.has_day_without_birds` function. It should take a list of daily bird counts. It should return `true` if there was at least one day when no birds visited the garden, and `false` otherwise. | ||
|
||
```gleam | ||
bird_count.has_day_without_birds([2, 0, 4]) | ||
// -> true | ||
bird_count.has_day_without_birds([3, 8, 1, 5]) | ||
// -> false | ||
``` | ||
|
||
## 4. Calculate the total number of visiting birds | ||
|
||
Implement the `bird_count.total` function. It should take a list of daily bird counts and return the total number that visited your garden since you started collecting the data. | ||
|
||
```gleam | ||
bird_count.total([4, 0, 9, 0, 5]) | ||
// -> 18 | ||
``` | ||
|
||
## 5. Calculate the number of busy days | ||
|
||
Some days are busier than others. A busy day is one where five or more birds have visited your garden. | ||
|
||
Implement the `bird_count.busy_days` function. It should take a list of daily bird counts and return the number of busy days. | ||
|
||
```gleam | ||
bird_count.busy_days([4, 5, 0, 0, 6]) | ||
// -> 2 | ||
``` | ||
|
||
## Source | ||
|
||
### Created by | ||
|
||
- @lpil |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
name = "bird_count" | ||
version = "0.1.0" | ||
|
||
[dependencies] | ||
gleam_bitwise = "~> 1.2" | ||
gleam_otp = "~> 0.7" | ||
gleam_stdlib = "~> 0.30" | ||
simplifile = "~> 0.1" | ||
|
||
[dev-dependencies] | ||
exercism_test_runner = "~> 1.4" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# This file was generated by Gleam | ||
# You typically do not need to edit this file | ||
|
||
packages = [ | ||
{ name = "exercism_test_runner", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "glance", "gleam_json", "gleam_community_ansi", "gleam_stdlib", "simplifile", "gap"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "336FBF790841C2DC25EB77B35E76A09EFDB9771D7D813E0FDBC71A50CB79711D" }, | ||
{ name = "gap", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib"], otp_app = "gap", source = "hex", outer_checksum = "AF290C27B3FAE5FE64E1B7E9C70A9E29AA0F42429C0592D375770C1C51B79D36" }, | ||
{ name = "glance", version = "0.7.1", build_tools = ["gleam"], requirements = ["gleam_stdlib", "glexer"], otp_app = "glance", source = "hex", outer_checksum = "B646A08970990D9D7A103443C5CD46F9D4297BF05F188767777FCC14ADF395EA" }, | ||
{ name = "gleam_bitwise", version = "1.3.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_bitwise", source = "hex", outer_checksum = "E2A46EE42E5E9110DAD67E0F71E7358CBE54D5EC22C526DD48CBBA3223025792" }, | ||
{ name = "gleam_community_ansi", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_bitwise", "gleam_community_colour"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "6E4E0CF2B207C1A7FCD3C21AA43514D67BC7004F21F82045CDCCE6C727A14862" }, | ||
{ name = "gleam_community_colour", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_bitwise"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "D27CE357ECB343929A8CEC3FBA0B499943A47F0EE1F589EE16AFC2DC21C61E5B" }, | ||
{ name = "gleam_erlang", version = "0.22.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "367D8B41A7A86809928ED1E7E55BFD0D46D7C4CF473440190F324AFA347109B4" }, | ||
{ name = "gleam_json", version = "0.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "C6CC5BEECA525117E97D0905013AB3F8836537455645DDDD10FE31A511B195EF" }, | ||
{ name = "gleam_otp", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "ED7381E90636E18F5697FD7956EECCA635A3B65538DC2BE2D91A38E61DCE8903" }, | ||
{ name = "gleam_stdlib", version = "0.31.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "6D1BC5B4D4179B9FEE866B1E69FE180AC2CE485AD90047C0B32B2CA984052736" }, | ||
{ name = "glexer", version = "0.6.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glexer", source = "hex", outer_checksum = "703D2347F5180B2BCEA4D258549B0D91DACD0905010892BAC46D04D913B84D1F" }, | ||
{ name = "simplifile", version = "0.1.14", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "10EA0207796F20488A3A166C50A189C9385333F3C9FAC187729DE7B9CE4ADDBC" }, | ||
{ name = "thoas", version = "0.4.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "4918D50026C073C4AB1388437132C77A6F6F7C8AC43C60C13758CC0ADCE2134E" }, | ||
] | ||
|
||
[requirements] | ||
exercism_test_runner = { version = "~> 1.4" } | ||
gleam_bitwise = { version = "~> 1.2" } | ||
gleam_otp = { version = "~> 0.7" } | ||
gleam_stdlib = { version = "~> 0.30" } | ||
simplifile = { version = "~> 0.1" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
pub fn today(days: List(Int)) -> Int { | ||
case days { | ||
[] -> 0 | ||
[first, ..] -> first | ||
} | ||
} | ||
|
||
pub fn increment_day_count(days: List(Int)) -> List(Int) { | ||
case days { | ||
[] -> [1] | ||
[first, ..rest] -> [first + 1, ..rest] | ||
} | ||
} | ||
|
||
pub fn has_day_without_birds(days: List(Int)) -> Bool { | ||
case days { | ||
[] -> False | ||
[0, ..] -> True | ||
[_first, ..rest] -> has_day_without_birds(rest) | ||
} | ||
} | ||
|
||
pub fn total(days: List(Int)) -> Int { | ||
case days { | ||
[] -> 0 | ||
[first, ..rest] -> first + total(rest) | ||
} | ||
} | ||
|
||
pub fn busy_days(days: List(Int)) -> Int { | ||
case days { | ||
[] -> 0 | ||
[first, ..rest] if first >= 5 -> 1 + busy_days(rest) | ||
[_first, ..rest] -> busy_days(rest) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import bird_count | ||
import exercism/test_runner | ||
import exercism/should | ||
|
||
pub fn main() { | ||
test_runner.main() | ||
} | ||
|
||
pub fn today_returns_0_if_no_birds_were_seen_test() { | ||
bird_count.today([]) | ||
|> should.equal(0) | ||
} | ||
|
||
pub fn today_returns_todays_bird_count_test() { | ||
bird_count.today([7]) | ||
|> should.equal(7) | ||
|
||
bird_count.today([2, 4, 11, 10, 6, 8]) | ||
|> should.equal(2) | ||
} | ||
|
||
pub fn today_create_entry_for_today_if_no_bird_watching_data_recorded_test() { | ||
bird_count.increment_day_count([]) | ||
|> should.equal([1]) | ||
} | ||
|
||
pub fn today_adds_1_to_todays_bird_count_test() { | ||
bird_count.increment_day_count([7]) | ||
|> should.equal([8]) | ||
|
||
bird_count.increment_day_count([4, 2, 1, 0, 10]) | ||
|> should.equal([5, 2, 1, 0, 10]) | ||
} | ||
|
||
pub fn has_day_without_birds_returns_false_if_no_bird_watching_data_recorded_test() { | ||
let assert False = bird_count.has_day_without_birds([]) | ||
} | ||
|
||
pub fn has_day_without_birds_returns_false_if_there_are_no_zeros_in_bird_watching_data_test() { | ||
let assert False = bird_count.has_day_without_birds([1]) | ||
} | ||
|
||
pub fn has_day_without_birds_returns_true_if_there_are_is_at_least_one_zero_in_bird_watching_data_test() { | ||
let assert True = bird_count.has_day_without_birds([0]) | ||
let assert True = bird_count.has_day_without_birds([4, 4, 0, 1]) | ||
let assert True = bird_count.has_day_without_birds([0, 0, 3, 0, 5, 6, 0]) | ||
} | ||
|
||
pub fn total_zero_if_no_bird_watching_data_recorded_test() { | ||
bird_count.total([]) | ||
|> should.equal(0) | ||
} | ||
|
||
pub fn total_sums_up_bird_counts_test() { | ||
bird_count.total([4]) | ||
|> should.equal(4) | ||
|
||
bird_count.total([3, 0, 0, 4, 4, 0, 0, 10]) | ||
|> should.equal(21) | ||
} | ||
|
||
pub fn busy_days_zero_if_no_bird_watching_data_recorded_test() { | ||
bird_count.busy_days([]) | ||
|> should.equal(0) | ||
} | ||
|
||
pub fn busy_days_counts_days_with_bird_count_of_5_or_more_test() { | ||
bird_count.busy_days([1]) | ||
|> should.equal(0) | ||
|
||
bird_count.busy_days([0, 5]) | ||
|> should.equal(1) | ||
|
||
bird_count.busy_days([0, 6, 10, 4, 4, 5, 0]) | ||
|> should.equal(3) | ||
} |