Skip to content

Commit

Permalink
Add robot-simulator exercise (#74)
Browse files Browse the repository at this point in the history
* add robot-simulator exercise

* add missing concepts + mutability->ownership

* add mutability back

* Add new uuid for ownership

* add author
  • Loading branch information
Nenad Misić authored Jul 11, 2024
1 parent d00dc83 commit 6332547
Show file tree
Hide file tree
Showing 12 changed files with 481 additions and 3 deletions.
7 changes: 7 additions & 0 deletions concepts/ownership/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"blurb": "<todo>",
"authors": [
"misicnenad"
],
"contributors": []
}
1 change: 1 addition & 0 deletions concepts/ownership/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Ownership
1 change: 1 addition & 0 deletions concepts/ownership/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Introduction
1 change: 1 addition & 0 deletions concepts/ownership/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
25 changes: 22 additions & 3 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@
"practices": [
"traits",
"type-conversion",
"mutability"
"mutability",
"ownership"
],
"prerequisites": [],
"difficulty": 4
Expand Down Expand Up @@ -203,7 +204,7 @@
"uuid": "9858a357-b935-437d-b4e0-c3aac20859cf",
"practices": [
"operator-overload",
"mutability",
"ownership",
"integers"
],
"prerequisites": [],
Expand All @@ -217,7 +218,7 @@
"traits",
"strings",
"arrays",
"mutability"
"ownership"
],
"prerequisites": [],
"difficulty": 5
Expand Down Expand Up @@ -246,6 +247,19 @@
"prerequisites": [],
"difficulty": 7
},
{
"slug": "robot-simulator",
"name": "Robot Simulator",
"uuid": "63302a7c-4235-41d6-9e10-9e46bd9a95c5",
"practices": [
"enums",
"traits",
"ownership",
"mutability"
],
"prerequisites": [],
"difficulty": 7
},
{
"slug": "protein-translation",
"name": "Protein Translation",
Expand Down Expand Up @@ -385,6 +399,11 @@
"slug": "mutability",
"name": "Mutability"
},
{
"uuid": "c11a8aa5-cda4-4d02-a477-3db3d3ca5acf",
"slug": "ownership",
"name": "Ownership"
},
{
"uuid": "7e322172-04ba-43f8-aba9-8ae999372b90",
"slug": "smart-pointers",
Expand Down
25 changes: 25 additions & 0 deletions exercises/practice/robot-simulator/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Instructions

Write a robot simulator.

A robot factory's test facility needs a program to verify robot movements.

The robots have three possible movements:

- turn right
- turn left
- advance

Robots are placed on a hypothetical infinite grid, facing a particular direction (north, east, south, or west) at a set of {x,y} coordinates,
e.g., {3,8}, with coordinates increasing to the north and east.

The robot then receives a number of instructions, at which point the testing facility verifies the robot's new position, and in which direction it is pointing.

- The letter-string "RAALAL" means:
- Turn right
- Advance twice
- Turn left
- Advance once
- Turn left yet again
- Say a robot starts at {7, 3} facing north.
Then running this stream of instructions should leave it at {9, 4} facing west.
19 changes: 19 additions & 0 deletions exercises/practice/robot-simulator/.meta/config.json
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"
]
},
"blurb": "Write a robot simulator.",
"source": "Inspired by an interview question at a famous company."
}
121 changes: 121 additions & 0 deletions exercises/practice/robot-simulator/.meta/example.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#[derive(Drop, Debug, Copy, PartialEq)]
enum Direction {
North,
East,
South,
West,
}

#[generate_trait]
impl DirectionImpl of DirectionTrait {
fn previous_clockwise(self: Direction) -> Direction {
match self {
Direction::North => Direction::West,
Direction::East => Direction::North,
Direction::South => Direction::East,
Direction::West => Direction::South,
}
}

fn next_clockwise(self: Direction) -> Direction {
match self {
Direction::North => Direction::East,
Direction::East => Direction::South,
Direction::South => Direction::West,
Direction::West => Direction::North,
}
}
}

#[derive(Drop, Copy)]
struct Position {
x: i32,
y: i32,
}

#[generate_trait]
impl PositionImpl of PositionTrait {
fn new(x: i32, y: i32) -> Position {
Position { x, y }
}

fn advance(self: Position, direction: @Direction) -> Position {
match *direction {
Direction::North => PositionImpl::new(self.x, self.y + 1),
Direction::South => PositionImpl::new(self.x, self.y - 1),
Direction::East => PositionImpl::new(self.x + 1, self.y),
Direction::West => PositionImpl::new(self.x - 1, self.y),
}
}
}

#[derive(Drop, Copy)]
struct Robot {
position: Position,
direction: Direction,
}

#[generate_trait]
impl RobotImpl of RobotTrait {
fn new(x: i32, y: i32, d: Direction) -> Robot {
RobotTrait::build(PositionTrait::new(x, y), d)
}

fn build(position: Position, direction: Direction) -> Robot {
Robot { position, direction, }
}

#[must_use]
fn turn_right(self: Robot) -> Robot {
RobotTrait::build(self.position, self.direction.next_clockwise())
}

#[must_use]
fn turn_left(self: Robot) -> Robot {
RobotTrait::build(self.position, self.direction.previous_clockwise())
}

#[must_use]
fn advance(self: Robot) -> Robot {
RobotTrait::build(self.position.advance(@self.direction), self.direction)
}

#[must_use]
fn instructions(self: Robot, instructions: ByteArray) -> Robot {
let mut robot = self.clone();
let mut i = 0;
loop {
match instructions.at(i) {
Option::None => { break robot; },
Option::Some(instruction) => {
robot = robot.execute(instruction.into());
i += 1;
}
}
}
}

fn position(self: @Robot) -> (i32, i32) {
(*self.position.x, *self.position.y)
}

fn direction(self: @Robot) -> @Direction {
self.direction
}

#[must_use]
fn execute(self: Robot, command: felt252) -> Robot {
if command == 'R' {
self.turn_right()
} else if command == 'L' {
self.turn_left()
} else if command == 'A' {
self.advance()
} else {
self
}
}
}

#[cfg(test)]
mod tests;
64 changes: 64 additions & 0 deletions exercises/practice/robot-simulator/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[c557c16d-26c1-4e06-827c-f6602cd0785c]
description = "Create robot -> at origin facing north"

[bf0dffce-f11c-4cdb-8a5e-2c89d8a5a67d]
description = "Create robot -> at negative position facing south"

[8cbd0086-6392-4680-b9b9-73cf491e67e5]
description = "Rotating clockwise -> changes north to east"

[8abc87fc-eab2-4276-93b7-9c009e866ba1]
description = "Rotating clockwise -> changes east to south"

[3cfe1b85-bbf2-4bae-b54d-d73e7e93617a]
description = "Rotating clockwise -> changes south to west"

[5ea9fb99-3f2c-47bd-86f7-46b7d8c3c716]
description = "Rotating clockwise -> changes west to north"

[fa0c40f5-6ba3-443d-a4b3-58cbd6cb8d63]
description = "Rotating counter-clockwise -> changes north to west"

[da33d734-831f-445c-9907-d66d7d2a92e2]
description = "Rotating counter-clockwise -> changes west to south"

[bd1ca4b9-4548-45f4-b32e-900fc7c19389]
description = "Rotating counter-clockwise -> changes south to east"

[2de27b67-a25c-4b59-9883-bc03b1b55bba]
description = "Rotating counter-clockwise -> changes east to north"

[f0dc2388-cddc-4f83-9bed-bcf46b8fc7b8]
description = "Moving forward one -> facing north increments Y"

[2786cf80-5bbf-44b0-9503-a89a9c5789da]
description = "Moving forward one -> facing south decrements Y"

[84bf3c8c-241f-434d-883d-69817dbd6a48]
description = "Moving forward one -> facing east increments X"

[bb69c4a7-3bbf-4f64-b415-666fa72d7b04]
description = "Moving forward one -> facing west decrements X"

[e34ac672-4ed4-4be3-a0b8-d9af259cbaa1]
description = "Follow series of instructions -> moving east and north from README"

[f30e4955-4b47-4aa3-8b39-ae98cfbd515b]
description = "Follow series of instructions -> moving west and north"

[3e466bf6-20ab-4d79-8b51-264165182fca]
description = "Follow series of instructions -> moving west and south"

[41f0bb96-c617-4e6b-acff-a4b279d44514]
description = "Follow series of instructions -> moving east and north"
4 changes: 4 additions & 0 deletions exercises/practice/robot-simulator/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "robot_simulator"
version = "0.1.0"
edition = "2023_11"
51 changes: 51 additions & 0 deletions exercises/practice/robot-simulator/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// The code below is a stub. Just enough to satisfy the compiler.
// In order to pass the tests you can add-to or change any of this code.

#[derive(Drop, PartialEq, Debug)]
enum Direction {
North,
East,
South,
West,
}

#[derive(Drop)]
struct Robot {}

#[generate_trait]
impl RobotImpl of RobotTrait {
fn new(x: i32, y: i32, d: Direction) -> Robot {
panic!("Create a robot at (x, y) facing {d:?}")
}

#[must_use]
fn turn_right(self: Robot) -> Robot {
panic!()
}

#[must_use]
fn turn_left(self: Robot) -> Robot {
panic!()
}

#[must_use]
fn advance(self: Robot) -> Robot {
panic!()
}

#[must_use]
fn instructions(self: Robot, instructions: ByteArray) -> Robot {
panic!("Follow the given sequence of instructions: {instructions}")
}

fn position(self: @Robot) -> (i32, i32) {
panic!()
}

fn direction(self: @Robot) -> @Direction {
panic!()
}
}

#[cfg(test)]
mod tests;
Loading

0 comments on commit 6332547

Please sign in to comment.