-
-
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 the
chrono-realms-chrono-chain
Exercise (#322)
* add introduction.md * update descr in control-flow links * add missing comma in control-flow blurb * Add smart pointers concept * rewrite introduction.md * add hints * write blurb * format md files * add design * update link in hints * add more tests + update to be trait-based * Update config.json prerequisites * delete redundant whitespace in links * ignore all non-first tests * remove redundant comments from tests * turn time-tree into chrono-chain * remove test_ from test names * remove changes to concepts
- Loading branch information
Showing
17 changed files
with
439 additions
and
134 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
18 changes: 18 additions & 0 deletions
18
exercises/concept/chrono-realms-chrono-chain/.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,18 @@ | ||
# Hints | ||
|
||
## General | ||
|
||
- [The Cairo Book: Smart Pointers][smart-pointers] | ||
|
||
## 1. Build the ChronoChain from an array of `u32` values | ||
|
||
- We can iterate through the array and construct a chain in reverse, starting from the `End` and linking each value with the `Link` variant. | ||
- Consider using `span.pop_back()` to iterate through the array in reverse order, this will help us create the chain from the end to the start. | ||
|
||
## 2. Sum the values in the ChronoChain | ||
|
||
- Use pattern matching to handle the two variants of `ChronoChain`. | ||
- When you reach `End`, the sum is 0, and when you reach `Link`, you add the value and recursively sum the rest of the chain. | ||
- This approach is similar to a recursive function that traverses the structure until it reaches the base case (`End`). | ||
|
||
[smart-pointers]: https://book.cairo-lang.org/ch11-02-smart-pointers.html |
46 changes: 46 additions & 0 deletions
46
exercises/concept/chrono-realms-chrono-chain/.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,46 @@ | ||
# Instructions | ||
|
||
In **Chrono Realms**, Time Keepers often deal with not just trees of timelines, but **Chrono Chains**-sequences of linked **TimeNodes**, each representing a specific moment in time. | ||
A **Chrono Chain** is a straight path of sequential moments, where each **TimeNode** connects to the next. | ||
These **Chrono Chains** are useful when traveling through a series of specific events, as they allow Time Keepers to follow a single timeline. | ||
|
||
However, to handle these potentially long **Chrono Chains**, Time Keepers use **Smart Pointers (Box<T>)** to safely manage and traverse these lists of moments without causing unnecessary memory duplication or overflow. | ||
Each **TimeNode** holds a reference to the next node, forming a recursive structure. | ||
|
||
Your task as an apprentice is to implement a **Chrono Chain** as a recursive list structure using smart pointers. | ||
|
||
In this exercise, you will: | ||
|
||
1. Create a recursive `ChronoChain` enum, representing a list of moments. | ||
2. Use the `Box<T>` smart pointer to store the recursive nodes. | ||
3. Implement a function to create a `ChronoChain` from an array of `u32` values. | ||
4. Implement a function to traverse the `ChronoChain` and sum up the values stored in the list. | ||
|
||
## 1. Define the Recursive `ChronoChain` Enum | ||
|
||
Create a recursive enum `ChronoChain` with two variants: | ||
|
||
- `End`: Represents the end of the list. | ||
- `Link`: Contains a `u32` value and a boxed reference to the next node in the chain. | ||
|
||
## 2. Create a Function to Build a ChronoChain | ||
|
||
Write a function `ChronoChain::build` that takes an array of `u32` values and returns a `ChronoChain`, linking the values sequentially using smart pointers. | ||
|
||
## 3. Implement the Sum Function | ||
|
||
Write a function `ChronoChain::sum` to recursively traverse the `ChronoChain` and sum the values of all nodes. | ||
|
||
## Example Usage | ||
|
||
```rust | ||
fn main() { | ||
// Create a ChronoChain from an array of values | ||
let chrono_chain = ChronoChain::build(array![10, 20, 30]); | ||
|
||
// Sum the values in the ChronoChain | ||
let total_sum = chrono_chain.sum(); | ||
|
||
println!("Total Time Power: {}", total_sum); | ||
} | ||
``` |
52 changes: 52 additions & 0 deletions
52
exercises/concept/chrono-realms-chrono-chain/.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,52 @@ | ||
# Introduction | ||
|
||
Smart pointers in Cairo are advanced data structures that ensure safe and efficient memory management by adding safety features to regular pointers, preventing common issues like dereferencing null pointers or accessing uninitialized memory. | ||
|
||
## What is a Smart Pointer? | ||
|
||
A smart pointer behaves like a regular pointer but tracks ownership and ensures safe memory access, preventing issues like null or dangling pointer dereferencing. | ||
|
||
## Types of Smart Pointers | ||
|
||
Cairo provides several smart pointer types, such as `Box<T>` and `Nullable<T>`: | ||
|
||
- **`Box<T>`**: Stores data in a special memory segment, ideal for large or dynamically-sized data. | ||
It allows transferring ownership without copying the data. | ||
- **`Nullable<T>`**: Points to either a valid value of type `T` or `null`, useful for handling optional values. | ||
|
||
## Memory Safety | ||
|
||
Smart pointers help prevent unsafe memory access, ensuring memory is automatically deallocated when no longer needed, thus reducing the risk of memory leaks. | ||
|
||
### Example: Using `Box<T>` for Recursive Types | ||
|
||
Smart pointers like `Box<T>` allow for safe handling of recursive types, such as in a binary tree, by allocating memory efficiently and avoiding infinite recursion. | ||
|
||
```rust | ||
use core::box::{BoxTrait}; | ||
|
||
#[derive(Copy, Drop)] | ||
enum BinaryTree { | ||
Leaf: u32, | ||
Node: (u32, Box<BinaryTree>, Box<BinaryTree>), | ||
} | ||
|
||
fn main() { | ||
let leaf1 = BinaryTree::Leaf(1); | ||
let leaf2 = BinaryTree::Leaf(2); | ||
let node = BinaryTree::Node((3, BoxTrait::new(leaf1), BoxTrait::new(leaf2))); | ||
println!("{:?}", node); | ||
} | ||
``` | ||
|
||
## Performance Benefits | ||
|
||
Smart pointers improve performance by passing references to data instead of copying large structures, reducing memory overhead. | ||
|
||
```rust | ||
// `Cart` is a large struct that contains a lot of information | ||
fn pass_pointer(cart: Box<Cart>) { | ||
let cart = cart.unbox(); | ||
println!("{} is shopping today and bought {} items", cart.buyer, cart.items); | ||
} | ||
``` |
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
36 changes: 36 additions & 0 deletions
36
exercises/concept/chrono-realms-chrono-chain/.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,36 @@ | ||
# Design | ||
|
||
## Goal | ||
|
||
Introduce the student to working with recursive types and smart pointers in Cairo. | ||
|
||
## Learning objectives | ||
|
||
- Understand how to define and use recursive types with enums in Cairo. | ||
- Learn how to use smart pointers (`Box<T>`) for handling recursive data structures. | ||
- Practice working with recursive functions to traverse and manipulate linked data. | ||
|
||
## Out of scope | ||
|
||
- Advanced memory management concepts related to smart pointers beyond `Box<T>`. | ||
- Deep dive into optimization of recursive data structures. | ||
|
||
## Concepts | ||
|
||
- Enums | ||
- Recursive types | ||
- Smart pointers (`Box<T>`) | ||
|
||
## Prerequisites | ||
|
||
- Traits | ||
- Basic understanding of enums and data types in Cairo. | ||
- Familiarity with smart pointers in Cairo. | ||
|
||
## Resources to refer to | ||
|
||
- [Cairo Book - The Box Type][box] | ||
- [Cairo Book - Enums][enums] | ||
|
||
[box]: https://book.cairo-lang.org/ch11-02-smart-pointers.html#the-boxt-type-to-manipulate-pointers | ||
[enums]: https://book.cairo-lang.org/ch06-01-enums.html |
30 changes: 30 additions & 0 deletions
30
exercises/concept/chrono-realms-chrono-chain/.meta/exemplar.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,30 @@ | ||
// Define the recursive ChronoChain enum | ||
#[derive(Copy, Drop)] | ||
pub enum ChronoChain { | ||
End, | ||
Link: (u32, Box<ChronoChain>), | ||
} | ||
|
||
#[generate_trait] | ||
pub impl ChronoChainImpl of ChronoChainTrait { | ||
// Function to build a ChronoChain from an array of u32 values | ||
fn build(arr: Array<u32>) -> ChronoChain { | ||
let mut chain = ChronoChain::End; | ||
|
||
// Iterate in reverse to build the chain from the end to the beginning | ||
let mut span = arr.span(); | ||
while let Option::Some(value) = span.pop_back() { | ||
chain = ChronoChain::Link((*value, BoxTrait::new(chain))); | ||
}; | ||
|
||
chain | ||
} | ||
|
||
// Function to sum the values in the ChronoChain | ||
fn sum(self: ChronoChain) -> u64 { | ||
match self { | ||
ChronoChain::End => 0, | ||
ChronoChain::Link((value, next)) => value.into() + next.unbox().sum(), | ||
} | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
...oncept/chrono-realms-time-tree/Scarb.toml → ...ept/chrono-realms-chrono-chain/Scarb.toml
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
19 changes: 19 additions & 0 deletions
19
exercises/concept/chrono-realms-chrono-chain/src/lib.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,19 @@ | ||
// Define the recursive ChronoChain enum | ||
#[derive(Copy, Drop)] | ||
pub enum ChronoChain { | ||
End, | ||
Link: (u32, Box<ChronoChain>), | ||
} | ||
|
||
#[generate_trait] | ||
pub impl ChronoChainImpl of ChronoChainTrait { | ||
// Function to build a ChronoChain from an array of u32 values | ||
fn build(arr: Array<u32>) -> ChronoChain { | ||
panic!("implement `ChronoChain::build`") | ||
} | ||
|
||
// Function to sum the values in the ChronoChain | ||
fn sum(self: ChronoChain) -> u64 { | ||
panic!("implement `ChronoChain::sum`") | ||
} | ||
} |
Oops, something went wrong.