-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Lucians Luscious Lasagna exercise
- Loading branch information
Nenad
committed
Jun 20, 2024
1 parent
e29a83b
commit a810c87
Showing
10 changed files
with
370 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
37 changes: 37 additions & 0 deletions
37
exercises/practice/lucians-luscious-lasagna/.docs/hints.md
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,37 @@ | ||
# Hints | ||
|
||
## General | ||
|
||
- An integer literal can be defined as one or more consecutive digits. | ||
|
||
## 1. Define the expected oven time in minutes | ||
|
||
- You need to define a [function][functions] without any parameters. | ||
|
||
## 2. Calculate the remaining oven time in minutes | ||
|
||
- You need to define a [function][functions] with a single parameter. | ||
- You can use and refer to the previously defined item by its name. | ||
- The last expression in a function is [automatically returned][return-values] | ||
from the function; you don't have to explicitly indicate which value to | ||
return. | ||
- You can use the [mathematical operator for subtraction][operators] to | ||
subtract values. | ||
|
||
## 3. Calculate the preparation time in minutes | ||
|
||
- You need to define a [function][functions] with a single parameter. | ||
- You can use the [mathematical operator for multiplication][operators] to | ||
multiply values. | ||
|
||
## 4. Calculate the elapsed time in minutes | ||
|
||
- You need to define a [function][functions] with two parameters. | ||
- You can [call][functions] one of the other functions you've defined | ||
previously. | ||
- You can use the [mathematical operator for addition][operators] to add | ||
values. | ||
|
||
[functions]: https://book.cairo-lang.org/ch02-03-functions.html | ||
[return-values]: https://book.cairo-lang.org/ch02-03-functions.html#functions-with-return-values | ||
[operators]: https://book.cairo-lang.org/appendix-02-operators-and-symbols.html |
55 changes: 55 additions & 0 deletions
55
exercises/practice/lucians-luscious-lasagna/.docs/instructions.md
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,55 @@ | ||
# Instructions | ||
|
||
In this exercise you're going to write some code to help you cook a brilliant | ||
lasagna from your favorite cooking book. | ||
|
||
You have four tasks, all related to the time spent cooking the lasagna. | ||
|
||
## 1. Define the expected oven time in minutes | ||
|
||
Define the `expected_minutes_in_oven` binding to check how many minutes the | ||
lasagna should be in the oven. According to the cooking book, the expected | ||
oven time in minutes is 40: | ||
|
||
```rust | ||
expected_minutes_in_oven() | ||
// Returns: 40 | ||
``` | ||
|
||
## 2. Calculate the remaining oven time in minutes | ||
|
||
Define the `remaining_minutes_in_oven` function that takes the actual minutes | ||
the lasagna has been in the oven as a parameter and returns how many minutes | ||
the lasagna still has to remain in the oven, based on the expected oven time | ||
in minutes from the previous task. | ||
|
||
```rust | ||
remaining_minutes_in_oven(30) | ||
// Returns: 10 | ||
``` | ||
|
||
## 3. Calculate the preparation time in minutes | ||
|
||
Define the `preparation_time_in_minutes` function that takes the number of | ||
layers you added to the lasagna as a parameter and returns how many minutes you | ||
spent preparing the lasagna, assuming each layer takes you 2 minutes to | ||
prepare. | ||
|
||
```rust | ||
preparation_time_in_minutes(2) | ||
// Returns: 4 | ||
``` | ||
|
||
## 4. Calculate the elapsed time in minutes | ||
|
||
Define the `elapsed_time_in_minutes` function that takes two parameters: the | ||
first parameter is the number of layers you added to the lasagna, and the | ||
second parameter is the number of minutes the lasagna has been in the oven. | ||
The function should return how many minutes you've worked on cooking the | ||
lasagna, which is the sum of the preparation time in minutes, and the time in | ||
minutes the lasagna has spent in the oven at the moment. | ||
|
||
```rust | ||
elapsed_time_in_minutes(3, 20) | ||
// Returns: 26 | ||
``` |
134 changes: 134 additions & 0 deletions
134
exercises/practice/lucians-luscious-lasagna/.docs/introduction.md
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,134 @@ | ||
# Introduction | ||
|
||
In Cairo, assigning a value to a name is referred to as a _binding_. Bindings | ||
are immutable unless declared with the `mut` keyword. As Cairo is a | ||
statically-typed language, each binding has a type known at compile-time. | ||
|
||
Bindings are most commonly defined using the `let` keyword. Specifying a | ||
binding's type is optional for most bindings, as Cairo's _type inference_ | ||
can usually infer the type based on their value. A binding looks like this: | ||
|
||
```rust | ||
// Automatically inferred type | ||
let fingers = 10; | ||
``` | ||
|
||
Functions are _items_. Where bindings typically refer to a particular value, | ||
items refer to a unit of code organization, typically a function or a module, | ||
which is available throughout the lifetime of the program. A function | ||
automatically returns the result of its last expression. A function may have 0 | ||
or more parameters, which are bindings with a lifetime of the function call. | ||
|
||
Type inference is theoretically possible for functions, but is disabled as an | ||
intentional language design choice. While this means that you need to spend a | ||
little more time when writing code to specify precisely what a function's input | ||
and output types are, you save the time when you're reading the code, because | ||
all the input and output types are explicitly defined. | ||
|
||
```rust | ||
fn add(x: i32, y: i32) -> i32 { | ||
x + y | ||
} | ||
``` | ||
|
||
Invoking a function is done by specifying its name followed by parentheses. | ||
If the function requires parameters, an argument must be specified for each | ||
within the parentheses. | ||
|
||
```rust | ||
let five = add(2, 3); | ||
``` | ||
|
||
If a binding's type cannot be inferred, the compiler will report an error. To | ||
fix this, add an explicit type annotation to the binding. | ||
|
||
```rust | ||
// Explicit type annotation | ||
let fingers: i32 = 10; | ||
``` | ||
|
||
Items in Cairo can be used before or after they are defined, because they have | ||
a static lifetime. Bindings, on the other hand, can only be used _after_ they | ||
have been defined. Using a binding before it has been defined results in a | ||
compile error. | ||
|
||
```rust | ||
fn main() { | ||
// `fn add` hasn't yet been defined, but that's perfectly ok | ||
dbg!(add(3, 4)); | ||
} | ||
|
||
fn add(x: i32, y: i32) -> i32 { | ||
x + y | ||
} | ||
``` | ||
|
||
```rust | ||
// this won't compile; `a` is used before its binding is defined | ||
let b = a; | ||
let a = x + y; | ||
``` | ||
|
||
Cairo uses curly braces (`{}`) to define a scope. A binding defined within a | ||
scope can't escape from it. | ||
|
||
```rust | ||
let a = 1; | ||
dbg!(a); // 1 | ||
{ | ||
// Here, we re-bind `a` to a new value, which is still immutable. | ||
// This technique is called _shadowing_. The new binding is constrained to | ||
// this anonymous scope. Outside this scope, the previous binding still | ||
// applies. | ||
let a = 2; | ||
let b = 3; | ||
dbg!(a, b); // 2, 3 | ||
} | ||
// can't use `b` anymore because it is out of scope | ||
// dbg!(b); | ||
|
||
// The shadowed `a` in the inner scope above has fallen out of scope, | ||
// leaving us with our original binding. | ||
dbg!(a); // 1 | ||
``` | ||
|
||
Cairo items are often organized in modules. Each crate is implicitly a module, | ||
but it can define inner sub-modules of arbitrary depth. A module groups related | ||
functionality and is defined using the `mod` keyword. | ||
|
||
```rust | ||
mod calc_i32 { | ||
fn add(a: i32, b: i32) -> i32 { a + b } | ||
fn sub(a: i32, b: i32) -> i32 { a - b } | ||
fn mul(a: i32, b: i32) -> i32 { a * b } | ||
fn div(a: i32, b: i32) -> i32 { a / b } | ||
} | ||
``` | ||
|
||
Cairo supports two types of comments. The keyword `//` indicates a single-line | ||
comment; everything following the keyword until the end of the line is ignored. | ||
The keywords `/*` and `*/` indicate a multi-line comment; everything within | ||
those two keywords is ignored. It is idiomatic and good practice to prefer | ||
single-line comments. | ||
|
||
Cairo also supports doc-comments, which show up in the generated documentation | ||
produced by `cargo doc`. Outer doc comments are formed with the keyword `///`, | ||
which acts identically to the `//` keyword. They apply to the item which | ||
follows them, such as a function: | ||
|
||
```rust | ||
/// The `add` function produces the sum of its arguments. | ||
fn add(x: i32, y: i32) -> i32 { x + y } | ||
``` | ||
|
||
Inner doc comments are formed with the keyword `//!`, which acts identically to | ||
the `//` keyword. They apply to the item enclosing them, such as a module: | ||
|
||
```rust | ||
mod my_cool_module { | ||
//! This module is the bee's knees. | ||
} | ||
``` | ||
|
||
Doc comments can be of arbitrary length and contain markdown, which is rendered | ||
into the generated documentation. |
19 changes: 19 additions & 0 deletions
19
exercises/practice/lucians-luscious-lasagna/.meta/config.json
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,19 @@ | ||
{ | ||
"authors": [ | ||
"misicnenad" | ||
], | ||
"files": { | ||
"solution": [ | ||
"src/lib.cairo", | ||
"Scarb.toml" | ||
], | ||
"test": [ | ||
"src/tests.cairo" | ||
], | ||
"example": [ | ||
".meta/example.cairo" | ||
] | ||
}, | ||
"icon": "lasagna", | ||
"blurb": "Learn about the basics of Cairo by following a lasagna recipe." | ||
} |
37 changes: 37 additions & 0 deletions
37
exercises/practice/lucians-luscious-lasagna/.meta/design.md
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,37 @@ | ||
# Design | ||
|
||
## Learning objectives | ||
|
||
- Know how to define a function | ||
- Know how to return a value from a function | ||
|
||
## Out of scope | ||
|
||
- Know how to work with `const` values | ||
|
||
## Concepts | ||
|
||
- Functions | ||
|
||
## Prerequisites | ||
|
||
None | ||
|
||
## Resources to refer to | ||
|
||
### Hints | ||
|
||
- [Functions](https://book.cairo-lang.org/ch02-03-functions.html) | ||
- [Return values](https://book.cairo-lang.org/ch02-03-functions.html#functions-with-return-values) | ||
- [Operators](https://book.cairo-lang.org/appendix-02-operators-and-symbols.html) | ||
|
||
### After | ||
|
||
## Representer | ||
|
||
This exercise does not require any specific representation logic to be added to | ||
the representer. | ||
|
||
## Analyzer | ||
|
||
This exercise does not require any specific logic to be added to the analyzer. |
18 changes: 18 additions & 0 deletions
18
exercises/practice/lucians-luscious-lasagna/.meta/example.cairo
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,18 @@ | ||
pub fn expected_minutes_in_oven() -> u32 { | ||
40 | ||
} | ||
|
||
pub fn remaining_minutes_in_oven(actual_minutes_in_oven: u32) -> u32 { | ||
expected_minutes_in_oven() - actual_minutes_in_oven | ||
} | ||
|
||
pub fn preparation_time_in_minutes(number_of_layers: u32) -> u32 { | ||
number_of_layers * 2 | ||
} | ||
|
||
pub fn elapsed_time_in_minutes(number_of_layers: u32, actual_minutes_in_oven: u32) -> u32 { | ||
preparation_time_in_minutes(number_of_layers) + actual_minutes_in_oven | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests; |
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 @@ | ||
[package] | ||
name = "lucians_luscious_lasagna" | ||
version = "0.1.0" | ||
edition = "2023_11" |
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,22 @@ | ||
pub fn expected_minutes_in_oven() -> u32 { | ||
panic!("return expected minutes in the oven") | ||
} | ||
|
||
pub fn remaining_minutes_in_oven(actual_minutes_in_oven: u32) -> u32 { | ||
panic!( | ||
"calculate remaining minutes in oven given actual minutes in oven: {actual_minutes_in_oven}" | ||
) | ||
} | ||
|
||
pub fn preparation_time_in_minutes(number_of_layers: u32) -> u32 { | ||
panic!("calculate preparation time in minutes for number of layers: {number_of_layers}") | ||
} | ||
|
||
pub fn elapsed_time_in_minutes(number_of_layers: u32, actual_minutes_in_oven: u32) -> u32 { | ||
panic!( | ||
"calculate elapsed time in minutes for number of layers {number_of_layers} and actual minutes in oven {actual_minutes_in_oven}" | ||
) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests; |
34 changes: 34 additions & 0 deletions
34
exercises/practice/lucians-luscious-lasagna/src/tests.cairo
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,34 @@ | ||
use lucians_luscious_lasagna::{ | ||
elapsed_time_in_minutes, expected_minutes_in_oven, preparation_time_in_minutes, | ||
remaining_minutes_in_oven | ||
}; | ||
|
||
#[test] | ||
fn expected_minutes_in_oven_is_correct() { | ||
assert_eq!(40, expected_minutes_in_oven()); | ||
} | ||
|
||
#[test] | ||
fn remaining_minutes_in_oven_after_fifteen_minutes() { | ||
assert_eq!(15, remaining_minutes_in_oven(25)); | ||
} | ||
|
||
#[test] | ||
fn preparation_time_in_minutes_for_one_layer() { | ||
assert_eq!(2, preparation_time_in_minutes(1)); | ||
} | ||
|
||
#[test] | ||
fn preparation_time_in_minutes_for_multiple_layers() { | ||
assert_eq!(8, preparation_time_in_minutes(4)); | ||
} | ||
|
||
#[test] | ||
fn elapsed_time_in_minutes_for_one_layer() { | ||
assert_eq!(32, elapsed_time_in_minutes(1, 30)); | ||
} | ||
|
||
#[test] | ||
fn elapsed_time_in_minutes_for_multiple_layers() { | ||
assert_eq!(16, elapsed_time_in_minutes(4, 8)); | ||
} |