Skip to content

Commit 1f776f6

Browse files
committed
✨ (concepts) Add concept exercise bird-watcher
This is inspired by the same in csharp track. Provides introduction to for loops, arrays and a bit of iterators.
1 parent 796f2ca commit 1f776f6

File tree

11 files changed

+555
-0
lines changed

11 files changed

+555
-0
lines changed

config.json

+16
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,22 @@
3535
},
3636
"exercises": {
3737
"concept": [
38+
{
39+
"slug": "bird-watcher",
40+
"uuid": "ef6bdeea-56d5-44d9-8971-1ac3b3a8f624",
41+
"name": "Bird Watcher",
42+
"difficulty": 1,
43+
"concepts": [
44+
"for-loops",
45+
"ranges",
46+
"arrays"
47+
],
48+
"prerequisites": [
49+
"if-statements",
50+
"assignment"
51+
],
52+
"status": "wip"
53+
},
3854
{
3955
"slug": "lucians-luscious-lasagna",
4056
"uuid": "29a2d3bd-eec8-454d-9dba-4b2d7d071925",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Hints
2+
3+
## General
4+
5+
- The bird count per day is an array that contains exactly 7 integers.
6+
7+
## 1. Check what the counts were last week
8+
9+
- Define an array that contains last week's log.
10+
- Return the array as a result.
11+
12+
## 2. Check how many birds visited today
13+
14+
- Remember that the counts are ordered by day from oldest to most recent, with the last element representing today.
15+
- Accessing the last element can be done by using its (fixed) index (remember to start counting from zero).
16+
17+
## 3. Increment today's count
18+
19+
- Set the element representing today's count to today's count plus 1.
20+
21+
## 4. Check if there was a day with no visiting birds
22+
23+
- Use if statements for performing comparisions with array elements.
24+
- Use [`for in`][for-in] construct to loop over an array.
25+
26+
## 5. Calculate the number of visiting birds for the first x number of days
27+
28+
- A variable can be used to hold the count for the number of visiting birds.
29+
- The array can be looped over using [`for in`][for-in] construct.
30+
- The variable can be updated inside the loop.
31+
- Use `break` statement to stop a loop.
32+
33+
## 6. Calculate the number of busy days
34+
35+
- A variable can be used to hold the number of busy days.
36+
- A variable can be used to hold the current index while looping over an array.
37+
- The variable can be updated inside the loop.
38+
- A [conditional statement][if-statement] can be used inside the loop.
39+
40+
[if-statement]:
41+
https://doc.rust-lang.org/rust-by-example/flow_control/if_else.html
42+
[for-in]:
43+
https://doc.rust-lang.org/rust-by-example/flow_control/for.html#for-and-range
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Instructions
2+
3+
You're an avid bird watcher that keeps track of how many birds have visited your garden in the last seven days.
4+
5+
You have six tasks, all dealing with the numbers of birds that visited your garden.
6+
7+
## 1. Check what the counts were last week
8+
9+
For comparison purposes, you always keep a copy of last week's log nearby,
10+
which were: 0, 2, 5, 3, 7, 8 and 4. Implement the `last_week_log()` function
11+
that returns last week's log
12+
13+
```rust
14+
last_week_log();
15+
// => [0, 2, 5, 3, 7, 8, 4]
16+
```
17+
18+
## 2. Check how many birds visited today
19+
20+
Implement the `count_today()` function to return how many birds visited your garden today. The bird counts are ordered by day, with the first element being the count of the oldest day, and the last element being today's count.
21+
22+
```rust
23+
let watch_log = [ 2, 5, 0, 7, 4, 1 ];
24+
count_today(watch_log);
25+
// => 1
26+
```
27+
28+
## 3. Increment today's count
29+
30+
Implement the `log_today()` function to increment today's count:
31+
32+
```rust
33+
let watch_log = [ 2, 5, 0, 7, 4, 1 ];
34+
log_today(watch_log);
35+
count_today(watch_log);
36+
// => 2
37+
```
38+
39+
## 4. Check if there was a day with no visiting birds
40+
41+
Implement the `has_day_without_birds()` method that returns `true` if there was a day at which zero birds visited the garden; otherwise, return `false`:
42+
43+
```rust
44+
let watch_log = [ 2, 5, 0, 7, 4, 1 ];
45+
has_day_without_birds(watch_log);
46+
// => true
47+
```
48+
49+
## 5. Calculate the number of visiting birds for the first x number of days
50+
51+
Implement the `tally_days()` function that returns the number of birds that have visited your garden from the start of the week, but limit the count to the specified number of days from the start of the week.
52+
53+
```rust
54+
let watch_log = [ 2, 5, 0, 7, 4, 1 ];
55+
tally_days(watch_log, 4);
56+
// => 14
57+
```
58+
59+
## 6. Calculate the number of busy days
60+
61+
Some days are busier that others. A busy day is one where five or more birds have visited your garden.
62+
Implement the `calc_busy_days()` function to return the number of busy days:
63+
64+
```rust
65+
let watch_log = [ 2, 5, 0, 7, 4, 1 ];
66+
calc_busy_days(watch_log);
67+
// => 2
68+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
# Introduction
2+
3+
An `array` is a collection of objects of the same type `T`, stored in contiguous
4+
memory.
5+
Arrays are created using brackets `[]`, and their length, which is known
6+
at compile time, is part of their type signature `[T; length]`(...)
7+
8+
Unlike arrays in some other languages, arrays in Rust have a fixed length.
9+
10+
11+
## Arrays
12+
### Defining an array
13+
We write the values in an array as a comma-separated list inside square
14+
brackets:
15+
16+
```rust
17+
let my_array = [1, 2, 3, 4, 5];
18+
```
19+
20+
We write an array’s type using square brackets with the type of each element, a
21+
semicolon, and then the number of elements in the array, like so:
22+
23+
```rust
24+
let my_array: [i32; 5] = [1, 2, 3, 4, 5];
25+
```
26+
27+
Here, `i32` is the type of each element. After the semicolon, the number 5
28+
indicates the array contains five elements.
29+
30+
You can also initialize an array to contain the same value for each element by
31+
specifying the initial value, followed by a semicolon, and then the length of
32+
the array in square brackets, as shown here:
33+
34+
```rust
35+
let my_array = [3; 5];
36+
// => [3, 3, 3, 3, 3]
37+
```
38+
39+
### Accessing Array Elements
40+
You can access elements of an array using indexing, like this:
41+
42+
```rust
43+
let a = [1, 2, 3, 4, 5];
44+
45+
let first = a[0];
46+
let second = a[1];
47+
```
48+
49+
50+
### Invalid Array Element Access
51+
Let’s see what happens if you try to access an element of an array that is past
52+
the end of the array.
53+
54+
```rust
55+
let a = [1, 2, 3, 4, 5];
56+
57+
let sixth = a[5];
58+
```
59+
60+
The above program will fail to compile with an error similar to:
61+
```txt
62+
let value = a[5];
63+
^^^^^^^^^^^^ index out of bounds: the length is 5 but the index is 5
64+
```
65+
66+
Now consider when you don't know the index you want to access and it is provided
67+
to you via a function parameter or a user input:
68+
69+
```rust
70+
fn access_element(index: usize) -> i32 {
71+
let a = [1, 2, 3, 4, 5];
72+
return a[index];
73+
}
74+
75+
fn main() {
76+
access_element(5);
77+
}
78+
```
79+
80+
In this case, the Rust compiler cannot know if the index is out of bounds.
81+
The code will compile without errors but fail at runtime with the following error.
82+
83+
```txt
84+
thread 'main' panicked at 'index out of bounds: the len is 5 but the index is 5'
85+
```
86+
87+
88+
### Use as a type
89+
90+
An array type can be used as a variable type, function parameter or return type.
91+
92+
```rust
93+
let my_var: [i32; 5];
94+
95+
fn my_func(input: [i32; 5]) -> [i32; 5] {}
96+
```
97+
98+
### Changing array elements
99+
Like for any other variable, arrays also have to be defined using `mut` keyword
100+
to allow change.
101+
An element can be changed by using assignment operator while accessing it via an index.
102+
103+
```rust
104+
let mut my_array = [2, 2, 3];
105+
my_array[0] = 1;
106+
// => [1, 2, 3]
107+
```
108+
109+
In the above example, we access the first element via it's index 0 and assign a
110+
new value to it.
111+
112+
## For loops
113+
114+
It’s often useful to execute a block of code more than once.
115+
For this task, Rust provides several loops, which will run through the code
116+
inside the loop body to the end and then start immediately back at the
117+
beginning.
118+
119+
### `for` and range
120+
121+
The `for in` construct can be used to iterate through an `Iterator`.
122+
We will learn more about `Iterators` in later concepts.
123+
One of the easiest ways to create an iterator is to use the range notation `a..b`.
124+
This yields values from a (inclusive) to b (exclusive) in steps of one.
125+
126+
```rust
127+
// A for loop that iterates 10 times
128+
for n in 0..10 {
129+
// n will have a starting value of 0
130+
// n will have the last value as 9
131+
}
132+
```
133+
134+
Alternatively, `a..=b` can be used for a range that is inclusive on both ends. The above can be written as:
135+
136+
```rust
137+
// A for loop that iterates 10 times
138+
for n in 1..=10 {
139+
// n will have a starting value of 1
140+
// n will have the last value as 10
141+
}
142+
```
143+
144+
### Break and Continue a loop
145+
A for loop can be halted by using the `break` statement.
146+
147+
```rust
148+
// A for loop that iterates 10 times
149+
for n in 1..=10 {
150+
println!(n);
151+
break;
152+
}
153+
// => 1
154+
```
155+
156+
One can conditionally break a for loop as follows:
157+
158+
```rust
159+
// A for loop that iterates 10 times
160+
for n in 1..=10 {
161+
println!(n);
162+
if n == 5 {
163+
break;
164+
}
165+
}
166+
// => 1
167+
// => 2
168+
// => 3
169+
// => 4
170+
// => 5
171+
```
172+
173+
A `continue` statement can be used to skip over an iteration.
174+
```rust
175+
// A for loop that iterates 10 times
176+
for n in 1..=10 {
177+
println!(n);
178+
continue;
179+
}
180+
// => 1
181+
```
182+
183+
Similar to `break`, one can also conditionally use `continue`:
184+
185+
```rust
186+
// A for loop that iterates 10 times
187+
for n in 1..=10 {
188+
println!(n);
189+
if n >= 5 {
190+
continue;
191+
}
192+
}
193+
// => 1
194+
// => 2
195+
// => 3
196+
// => 4
197+
// => 5
198+
```
199+
200+
### Looping Through an Array with `for`
201+
The following shows an example of looping through an array using the `for in` construct.
202+
203+
```rust
204+
let a = [10, 20, 30, 40, 50];
205+
206+
for element in a {
207+
println!("the value is: {element}");
208+
}
209+
210+
// => the value is: 10
211+
// => the value is: 20
212+
// => the value is: 30
213+
// => the value is: 40
214+
// => the value is: 50
215+
216+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Generated by Cargo
2+
# will have compiled files and executables
3+
/target/
4+
**/*.rs.bk
5+
6+
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
7+
# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
8+
Cargo.lock
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"authors": [
3+
"devkabiir"
4+
],
5+
"files": {
6+
"solution": [
7+
"src/lib.rs",
8+
"Cargo.toml"
9+
],
10+
"test": [
11+
"tests/bird-watcher.rs"
12+
],
13+
"exemplar": [
14+
".meta/exemplar.rs"
15+
]
16+
},
17+
"blurb": "Learn about for loops and arrays by keeping track of how many birds visit your garden."
18+
}

0 commit comments

Comments
 (0)