diff --git a/10_Tennis/README.md b/10_Tennis/README.md index eb140e9..ba46972 100644 --- a/10_Tennis/README.md +++ b/10_Tennis/README.md @@ -4,11 +4,19 @@ -## The problem +## Problem Statement -Imagine you work for a consultancy company, and one of your colleagues has been doing some work for the Tennis Society. The contract is for 10 hours billable work, and your colleague has spent 8.5 hours working on it. Unfortunately he has now fallen ill. He says he has completed the work, and the tests all pass. Your boss has asked you to take over from him. She wants you to spend an hour or so on the code so she can bill the client for the full 10 hours. She instructs you to tidy up the code a little and perhaps make some notes so you can give your colleague some feedback on his chosen design. You should also prepare to talk to your boss about the value of this refactoring work, over and above the extra billable hours. +You are taking over a tennis scoring system project from a colleague who: - +- Has spent 8.5 hours of a 10-hour billable project +- Claims the work is complete with passing tests +- Is currently unavailable due to illness + +Your manager has requested you to: + +1. Spend the remaining billable time (~1 hour) improving the code +2. Prepare feedback on the current design +3. Be ready to discuss the value of refactoring beyond billable hours ## Your task diff --git a/1_FizzBuzz/README.md b/1_FizzBuzz/README.md index 04eddd6..42761d1 100644 --- a/1_FizzBuzz/README.md +++ b/1_FizzBuzz/README.md @@ -2,8 +2,8 @@ - Write a function that takes a number and returns it as a string. - For multiples of three return "fizz" instead of the stringified number. -- For the multiples of five return “buzz" instead of the strigified number. -- For numbers which are multiples of both three and five return “fizzbuzz" instead of the stringified number. +- For multiples of five return "buzz" instead of the stringified number. +- For numbers which are multiples of both three and five return "fizzbuzz" instead of the stringified number. ## Examples @@ -21,15 +21,15 @@ | **10** | "buzz" | | **11** | "11" | | **12** | "fizz" | -| **13** | "14" | -| **14** | "15" | +| **13** | "13" | +| **14** | "14" | | **15** | "fizzbuzz" | -## Folow TDD rules stryctly +## Follow TDD rules strictly -1. Write production code only to pass a single failing unit test. -2. Write no more of a unit test than sufficient to fail (compilation failures are failures). -3. Write no more production code than necessary to pass the one failing unit test. +1. ✅ Write production code only to pass a failing unit test +2. ✅ Write only enough of a unit test to make it fail +3. ✅ Write only enough production code to make the failing test pass ## Great habits diff --git a/20_Katacombs/katacombsAPI.yml b/20_Katacombs/katacombsAPI.yml index b8adf87..a463e33 100644 --- a/20_Katacombs/katacombsAPI.yml +++ b/20_Katacombs/katacombsAPI.yml @@ -1,8 +1,8 @@ openapi: 3.0.0 info: - description: This API allows playing a text based adventure game + description: This API allows playing a text-based adventure game called Katacombs version: 1.0.0 - title: Katacombs + title: Katacombs API license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html @@ -28,7 +28,11 @@ paths: $ref: "#/components/schemas/Player" responses: "201": - description: Game started + description: Game started successfully + content: + application/json: + schema: + $ref: "#/components/schemas/Player" get: tags: - Game @@ -58,12 +62,15 @@ paths: $ref: "#/components/schemas/Sid" responses: "200": - description: Game finished + description: Game finished successfully content: - text/plain: + application/json: schema: - type: string - example: Game Over + type: object + properties: + message: + type: string + example: "Game Over" "404": description: Player with Sid playerSid not found /player/items/{itemSid}: @@ -137,7 +144,15 @@ paths: $ref: "#/components/schemas/Action" responses: "200": - description: Action performed + description: Action performed successfully + content: + application/json: + schema: + type: object + properties: + message: + type: string + example: "Action completed successfully" "404": description: Player or Item with Sid playerSid not found "405": @@ -297,7 +312,7 @@ components: items: $ref: "#/components/schemas/Item" Player: - description: Player type + description: Player information type: object required: - sid @@ -307,7 +322,11 @@ components: $ref: "#/components/schemas/Sid" name: type: string - example: Pedro + example: "Pedro" + location: + $ref: "#/components/schemas/Location" + bag: + $ref: "#/components/schemas/Bag" Sid: description: Sid type type: string diff --git a/2_LeapYear/README.md b/2_LeapYear/README.md index 5c947d5..f290c73 100644 --- a/2_LeapYear/README.md +++ b/2_LeapYear/README.md @@ -2,9 +2,9 @@ Write a function that returns true or false depending on whether its input integer is a leap year or not. -- A leap year is defined as: +- A leap year is defined as one that: - - one that is divisible by 4 + - is divisible by 4 - but is not otherwise divisible by 100 - unless it is also divisible by 400. @@ -34,12 +34,12 @@ Write a function that returns true or false depending on whether its input integ | **1900** | false | | **2000** | true | -## Folow TDD rules stryctly +## Follow TDD rules strictly -1. Write production code only to pass a failing unit test. -2. Write no more of a unit test than sufficient to fail (compilation failures are failures). -3. Write no more production code than necessary to pass the one failing unit test. +1. ✅ Write production code only to pass a failing unit test +2. ✅ Write only enough of a unit test to make it fail +3. ✅ Write only enough production code to make the failing test pass ## Resources -TestDesiderata by Kent Beck: +- [TestDesiderata](https://kentbeck.github.io/TestDesiderata) by Kent Beck diff --git a/3_Fibonacci/README.md b/3_Fibonacci/README.md index a3ed19a..5bffa46 100644 --- a/3_Fibonacci/README.md +++ b/3_Fibonacci/README.md @@ -1,28 +1,51 @@ -# Fibonacci kata - -- Write a function to generate the Fibonacci number for the nth position. - - Example: int Fibonacci(int position) -- First Fibonacci numbers in the sequence are: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 - -| **Input** | **Output** | -| --------- | ---------- | -| **0** | 0 | -| **1** | 1 | -| **2** | 1 | -| **3** | 2 | -| **4** | 3 | -| **5** | 5 | -| **6** | 8 | -| **7** | 13 | -| **8** | 21 | -| **9** | 34 | - -## Folow TDD rules stryctly - -1. Write production code only to pass a failing unit test. -2. Write no more of a unit test than sufficient to fail (compilation failures are failures). -3. Write no more production code than necessary to pass the one failing unit test. +# Fibonacci Kata + +## Problem Description + +Write a function that returns the Fibonacci number at a given position. + +### Function Signature + +```typescript +function fibonacci(position: number): number; +``` + +### Sequence Definition + +The Fibonacci sequence is defined where each number is the sum of the two preceding ones, starting from 0 and 1. + +### Examples + +The first 10 Fibonacci numbers are: + +| Position | Value | +| -------- | ----- | +| 0 | 0 | +| 1 | 1 | +| 2 | 1 | +| 3 | 2 | +| 4 | 3 | +| 5 | 5 | +| 6 | 8 | +| 7 | 13 | +| 8 | 21 | +| 9 | 34 | + +## TDD Rules + +1. ✅ Write production code only to pass a failing unit test +2. ✅ Write only enough of a unit test to make it fail +3. ✅ Write only enough production code to make the failing test pass + +## Suggested Test Cases + +1. Test position 0 returns 0 +2. Test position 1 returns 1 +3. Test position 2 returns 1 +4. Test larger positions (e.g., 8 returns 21) +5. Test negative positions (should handle edge case) ## Resources -TestDesiderata by Kent Beck: +- [Test Desiderata by Kent Beck](https://kentbeck.github.io/TestDesiderata) +- [Fibonacci Sequence on Wikipedia](https://en.wikipedia.org/wiki/Fibonacci_number) diff --git a/4_StackKata/README.md b/4_StackKata/README.md index dafc7a9..1ef8541 100644 --- a/4_StackKata/README.md +++ b/4_StackKata/README.md @@ -1,24 +1,35 @@ -# Stack kata +# Stack Kata -- Implement a Stack class with the following public methods: - - `push(value: number) : void` - - `pop() : number` -- Stack should throw an exception if popped when empty. +## Requirements -| **push** | **pop** | -| -------- | ------- | -| -- | throw | -| 1 | 1 | -| 2 | 2 | -| 1, 2 | 2, 1 | -| 1, 2, 3 | 3, 2, 1 | +Implement a Stack class with the following public methods: -## Folow TDD rules stryctly +- `push(value: number): void` - Adds a value to the top of the stack +- `pop(): number` - Removes and returns the top value from the stack +- The stack should throw an exception when attempting to pop from an empty stack -1. Write production code only to pass a failing unit test. -2. Write no more of a unit test than sufficient to fail (compilation failures are failures). -3. Write no more production code than necessary to pass the one failing unit test. +## Test Cases + +| Input (push) | Expected Output (pop) | +| ------------ | --------------------- | +| Empty Stack | throws Exception | +| push(1) | 1 | +| push(2) | 2 | +| push(1,2) | 2, then 1 | +| push(1,2,3) | 3, then 2, then 1 | + +## TDD Rules + +1. ✅ Write production code only to pass a failing unit test +2. ✅ Write only enough of a unit test to make it fail +3. ✅ Write only enough production code to make the failing test pass + +## Additional Guidelines + +- Follow the "Red-Green-Refactor" cycle +- Keep tests and production code as simple as possible +- Commit after each successful test ## Resources -TestDesiderata by Kent Beck: +- [TestDesiderata by Kent Beck](https://kentbeck.github.io/TestDesiderata) diff --git a/5_RomanNumerals/README.md b/5_RomanNumerals/README.md index 12c012d..9088f09 100644 --- a/5_RomanNumerals/README.md +++ b/5_RomanNumerals/README.md @@ -3,7 +3,7 @@ ## First run - Implement a Roman numeral converter. -- The code must be able to take numbers up to 3999 and convert to their roman equivalent. +- The code must be able to take numbers up to 3999 and convert to their Roman equivalent. | **Arabic number** | **Roman numeral** | | ----------------- | ----------------- | @@ -38,27 +38,33 @@ | **2000** | MM | | **3000** | MMM | +## Follow TDD rules strictly + +1. ✅ Write production code only to pass a failing unit test +2. ✅ Write only enough of a unit test to make it fail +3. ✅ Write only enough production code to make the failing test pass + ## Second run -Use the Transformation Priority Premise table to evolve your code. +Use the Transformation Priority Premise (TPP) to evolve your code. ### TPP table -| # | Transformation | Start code | End code | -| --- | ---------------------------- | ------------------ | ---------------------------------------- | -| 1 | {} -> nil | {} | [return] nil | -| 2 | Nil -> constant | [return] nil | [return] “1” | -| 3 | Constant -> constant+ | [return] “1” | [return] “1” + “2” | -| 4 | Constant -> scalar | [return] “1” + “2” | [return] argument | -| 5 | Statement -> statements | [return] argument | [return] min(max(0, argument), 10) | -| 6 | Unconditional -> conditional | [return] argument | if(condition) [return] 1 else [return] 0 | -| 7 | Scalar -> array | dog | [dog, cat] | -| 8 | Array -> container | [dog, cat] | {dog=”DOG”, cat=”CAT”} | -| 9 | Statement -> tail recursion | a + b | a + recursion | -| 10 | If -> loop | if(condition) | loop(condition) | -| 11 | Statement -> recursion | a + recursion | recursion | -| 12 | Expression -> function | today – birth | CalculateBirthDate() | -| 13 | Variable -> mutation | day | var Day = 10; Day = 11; | +| # | Transformation | Start code | End code | +| --- | --------------------------- | ------------------ | ---------------------------------------- | +| 1 | {} → nil | {} | [return] nil | +| 2 | nil → constant | [return] nil | [return] "1" | +| 3 | constant → constant+ | [return] "1" | [return] "1" + "2" | +| 4 | constant → scalar | [return] "1" + "2" | [return] argument | +| 5 | statement → statements | [return] argument | [return] min(max(0, argument), 10) | +| 6 | unconditional → conditional | [return] argument | if(condition) [return] 1 else [return] 0 | +| 7 | scalar → array | dog | [dog, cat] | +| 8 | array → container | [dog, cat] | {dog="DOG", cat="CAT"} | +| 9 | statement → tail recursion | a + b | a + recursion | +| 10 | if → loop | if(condition) | loop(condition) | +| 11 | statement → recursion | a + recursion | recursion | +| 12 | expression → function | today – birth | calculateBirthDate() | +| 13 | variable → mutation | day | var day = 10; day = 11; | Transformations at the top of the list have priority over those at the bottom. It is better (or simpler) to change a constant into a variable than it is to add an `if` statement. So when making a test pass, favor simpler transformations (top of the list) over those more complicated (bottom of the list). @@ -66,17 +72,17 @@ Another way to use the Transformation Priority Premise is to keep writing new co ### Example using Transformation Priority Premise on Fibonacci sequence -| Input | Expected output | Transformation | Implementation | -| ----- | --------------- | ---------------------------- | ----------------------------------------------------------------------- | -| 0 | 0 | {} -> nil | :warning: Does not work | -| 0 | 0 | Nil -> constant | `return 0` | -| 1 | 1 | Constant -> scalar | `return index` | -| 2 | 1 | Unconditional -> conditional | `if number < 2 then return index else return index - 1` | -| 3 | 2 | Unconditional -> conditional | No change | -| 4 | 3 | Unconditional -> conditional | No change | -| 5 | 5 | Scalar -> array | `var fibs = [0, 1, 1, 2, 3, 5]; return fibs[index]` | -| 6 | 8 | Scalar -> array | `var fibs = [0, 1, 1, 2, 3, 5, 8]; return fibs[index]` | -| 7 | 13 | Scalar -> array(duplication) | `var fibs = [0, 1, 1, 2, 3, 5, 8, 13]; return fibs[index]` | -| 8 | 21 | Statement -> tail recursion | `if index < 2 return index else return fib(index - 1) + fib(index - 2)` | +| Input | Expected output | Transformation | Implementation | +| ----- | --------------- | --------------------------- | ----------------------------------------------------------------------- | +| 0 | 0 | {} → nil | :warning: Does not work | +| 0 | 0 | nil → constant | `return 0` | +| 1 | 1 | constant → scalar | `return index` | +| 2 | 1 | unconditional → conditional | `if number < 2 then return index else return index - 1` | +| 3 | 2 | unconditional → conditional | `if number < 2 then return index else return index - 1` NO CHANGE | +| 4 | 3 | unconditional → conditional | `if number < 2 then return index else return index - 1` NO CHANGE | +| 5 | 5 | scalar → array | `var fibs = [0, 1, 1, 2, 3, 5]; return fibs[index]` | +| 6 | 8 | scalar → array | `var fibs = [0, 1, 1, 2, 3, 5, 8]; return fibs[index]` | +| 7 | 13 | scalar → array(duplication) | `var fibs = [0, 1, 1, 2, 3, 5, 8, 13]; return fibs[index]` | +| 8 | 21 | statement → tail recursion | `if index < 2 return index else return fib(index - 1) + fib(index - 2)` | The Transformation Priority Premise aims to evolve code while keeping complexity under control. diff --git a/6_PrimeFactors/README.md b/6_PrimeFactors/README.md index e01f56f..001f644 100644 --- a/6_PrimeFactors/README.md +++ b/6_PrimeFactors/README.md @@ -1,23 +1,41 @@ -# Prime factors kata +# Prime Factors Kata -Factorize a positive integer number into its prime factors. +Write a function that decomposes a positive integer into its prime factors. -For example: +## Problem Description -| **Input** | **Output** | -| --------- | ---------- | -| 2 | [2] | -| 3 | [3] | -| 4 | [2,2] | -| 6 | [2,3] | -| 9 | [3,3] | -| 12 | [2,2,3] | -| 15 | [3,5] | +Given a positive integer, return an array of its prime factors in ascending order. A prime factor is a prime number that divides the input number without leaving a remainder. -## Folow TDD rules strictly +## Examples -1. Write production code only to pass a failing unit test. -2. Write no more of a unit test than sufficient to fail (compilation failures are failures). -3. Write no more production code than necessary to pass the one failing unit test. +| **Input** | **Output** | **Explanation** | +| --------- | ---------- | --------------- | +| 2 | `[2]` | 2 is prime | +| 3 | `[3]` | 3 is prime | +| 4 | `[2,2]` | 4 = 2 × 2 | +| 6 | `[2,3]` | 6 = 2 × 3 | +| 9 | `[3,3]` | 9 = 3 × 3 | +| 12 | `[2,2,3]` | 12 = 2 × 2 × 3 | +| 15 | `[3,5]` | 15 = 3 × 5 | -Source: +## TDD Rules + +Follow these Test-Driven Development rules strictly: + +1. ✅ Write production code only to pass a failing unit test +2. ✅ Write only enough of a unit test to make it fail +3. ✅ Write only enough production code to make the failing test pass + +## Getting Started + +1. Create a function that takes a positive integer as input +2. Return an array of prime factors +3. Follow the TDD cycle: Red → Green → Refactor + +## Edge Cases to Consider + +- Input of 1 should return an empty array +- Input must be a positive integer +- Large numbers should still work efficiently + +Source: [Cyber-Dojo](http://cyber-dojo.org/) diff --git a/7_TicTacToe/README.md b/7_TicTacToe/README.md index 9585c84..7fa16e3 100644 --- a/7_TicTacToe/README.md +++ b/7_TicTacToe/README.md @@ -14,9 +14,9 @@ ## Follow TDD rules strictly -1. Write production code only to pass a failing unit test. -2. Write no more of a unit test than sufficient to fail (compilation failures are failures). -3. Write no more production code than necessary to pass the one failing unit test. +1. ✅ Write production code only to pass a failing unit test +2. ✅ Write only enough of a unit test to make it fail +3. ✅ Write only enough production code to make the failing test pass ## First run @@ -24,7 +24,7 @@ Implement Tic Tac Toe as best as you can using TDD. ## Second run -Implement Tic Tac Toe striclly applying object calisthenics rules. +Implement Tic Tac Toe strictly applying object calisthenics rules. ## Object calisthenics diff --git a/8_Yahtzee/README.md b/8_Yahtzee/README.md index 6512621..7fa16e3 100644 --- a/8_Yahtzee/README.md +++ b/8_Yahtzee/README.md @@ -1,61 +1,81 @@ -# Yahtzee kata +# Tic Tac Toe kata ## Rules -The game of yahtzee is a simple dice game. - -Each round, players rolls five six sided dice. -The player may choose to reroll some or all of the dice up to three times (including the original roll). -The player then places the roll at a category, such as ones, twos, sixes, pair, two pairs etc. -If the roll is compatible with the score, the player gets a score for this roll according to the rules. -If the roll is not compatible, the player gets a score of zero for this roll. - -The kata consists of creating the rules to score rolls, calculate player totals and determine when game is finished. - -## Implementation - -### Offline (No need to implement this part) - -- Player rolls 5 die -- Player can re-roll any number of die -- Player can re-roll any number of die -- Player can re-roll any number of die - -### Implement - -- Player assigns final roll to a category (see catagory list below) -- Player cannot assign to an already assigned category -- Calculate score for player/roll/category - - If roll is compatible score using the category specific scoring rules - - If roll is not compatible score zero -- Update player score -- Game finishes when all players have assigned rolls to all categories - -### Categories - -- Ones, Twos, Threes, Fours, Fives, Sixes - - The player scores the sum of the dice that reads one, two, three, four, five or six, respectively. - - Example roll: 1, 1, 2, 4, 4 placed on “fours” scores 8 points. -- Pair - - The player scores the sum of the two highest matching dice. - - Example roll: 3, 3, 3, 4, 4 placed on “pair” scores 8. -- Two pairs - - If there are two pairs of dice with the same number, the player scores the sum of these dice. - - For example, 1, 1, 2, 3, 3 placed on “two pairs” scores 8. -- Three of a kind - - If there are three dice with the same number, the player scores the sum of these dice. - - Example roll: 3, 3, 3, 4, 5 places on “three of a kind” scores 9. -- Four of a kind - - If there are four dice with the same number, the player scores the sum of these dice. - - Example roll: 2, 2, 2, 2, 5 places on “four of a kind” scores 8. -- Small straight - - If the roll starts on 1 - - Example roll: 1,2,3,4,5, the player scores 15 (the sum of all the dice). -- Large straight - - If the roll starts on 2 - - Example roll: 2,3,4,5,6, the player scores 20 (the sum of all the dice). -- Full house - - If the dice are two of a kind and three of a kind, the player scores the sum of all the dice. - - Example roll: 1,1,2,2,2 placed on “full house” scores 8. -- Yahtzee - - If all dice have the same number, the player scores 50 points. +- The game is played on a grid that's 3 squares by 3 squares +- Players alternate placing X’s and O’s in empty squares +- X always plays first +- Players cannot play on a played square +- A Player wins when it has three squares in a row + - Horizontally + - Vertically + - Diagonally +- If all nine squares are filled and neither player has won, the game is a draw + +## Follow TDD rules strictly + +1. ✅ Write production code only to pass a failing unit test +2. ✅ Write only enough of a unit test to make it fail +3. ✅ Write only enough production code to make the failing test pass + +## First run + +Implement Tic Tac Toe as best as you can using TDD. + +## Second run + +Implement Tic Tac Toe strictly applying object calisthenics rules. + +## Object calisthenics + +### In order of importance (defined by Pedro) + +- Wrap all primitives and strings + - Wrap primitives in a type, specially if it has behaviour or it’s an important domain concept +- First class collections + - Wrap collections in a type, specially if it has behaviour or it’s an important domain concept +- One dot per line + - Do not write dog.Body.Tail.Wag() write dog.ExpressHappiness() - Law of Demeter +- No getters/setters/properties, no access to private data, none! - TELL DON’T ASK! +- No classes with more than two instance variables +- Only one level of indentation per method +- Don't use the ELSE keyword +- Don't abbreviate names +- Keep all entities small + - 10 files per package/namespace + - 50 lines per class + - 5 lines per method + - 2-3? arguments per method + +## Great habits + +### Considerations when writing a new test + +- Tests should test one thing only. +- Create more specific tests to drive a more generic solution (triangulate). +- Give your tests meaningful names (behavior/goal-oriented) that reflect your business domain. +- See the test fail for the right reason. +- Ensure you have meaningful feedback from failing tests. +- Keep your tests and production code separate. +- Organize your unit tests to reflect your production code (similar project structure). +- Organize your test in arrange, act and assert blocks. +- Write the, or at least focus on the, assertion first and work backward. +- Write fast, isolated, repeatable and self-validating tests. + +### Considerations when making a failing test pass + +- Write the simplest code to pass the test. +- Write any code that makes you get to the refactor phase quicker. +- Use Transformation Priority Premise. +- Consider using object calisthenics to drive design decisions. + +### Considerations after the test passes + +- Use the Rule of Three to tackle duplication. +- Refactor design constantly. +- Apply object calisthenics to improve your design. + +## Resources + + + diff --git a/9_MarsRover/README.md b/9_MarsRover/README.md index 602257e..18e36df 100644 --- a/9_MarsRover/README.md +++ b/9_MarsRover/README.md @@ -1,120 +1,106 @@ # Mars Rover kata -## Problem +## Problem Description -A robot rover is landed by NASA on a plateau on Mars. -The plateau is divided up into a grid to simplify navigation. -This plateau, must be navigated by the rover so that it´s on-board cameras can get a complete view of the surrounding terrain to send back to Earth. +A NASA robot rover has landed on Mars. The rover must navigate a rectangular plateau divided into a grid, capturing terrain images with its on-board cameras to send back to Earth. -## Input +## Input Specification -- The rover receives three lines of input: - - The first line defines the upper-right coordinates of the plateau. - - Example: ‘5:5’ - - The lower-left coordinates are always ‘0:0’. - - The second line contains the rover’s starting position and direction. - - Example ‘1:2:N’ measn x=1, y=2 and Direction=North - - Assume that the square directly North from (x, y) is (x, y+1). - - The third line contains the sequence of commands to execute. - - Example: ‘LMLMLMLMM’ - - ‘L’ and ‘R’ makes the rover spin 90 degrees left or right respectively, without moving from its current spot. - - ‘M’ means move forward one grid point, and maintain the same heading. +The rover accepts three lines of input: -### Example input +1. **Plateau Size**: Upper-right coordinates (e.g., `5 5`) + + - Lower-left coordinates are always `0 0` + - Format: ` ` + +2. **Initial Position**: Starting position and direction (e.g., `1 2 N`) + + - Format: ` ` + - Direction can be N(orth), E(ast), S(outh), or W(est) + - Moving North from (x, y) leads to (x, y+1) + +3. **Command Sequence**: Series of movement instructions (e.g., `LMLMLMLMM`) + - `L`: Rotate 90° left + - `R`: Rotate 90° right + - `M`: Move forward one grid point + +### Sample Input ```text -5:5 -1:2:N -MLMLMLMM +5 5 +1 2 N +LMLMLMLMM ``` -Assume that NASA will never send invalid messages to the rover, nor will it send a message moving the rover outside the defined grid. +**Note**: NASA guarantees valid input messages within the defined grid. + +## Output Specification -## Output +The rover reports its final coordinates and heading. -The output for the rover should be its final co-ordinates and heading. +### Sample Output ```text -1:3:N +1 3 N ``` -## Examples +## Test Cases -### Input 1 +### Test Case 1 + +Input: ```text -5:5 -1:2:N +5 5 +1 2 N LMLMLMLMM ``` -### Expected Output 1 +Output: ```text -1:3:N +1 3 N ``` -### Input 2 +### Test Case 2 + +Input: ```text -5:5 -3:3:E +5 5 +3 3 E MMRMMRMRRM ``` -### Expected Output 2 +Output: ```text -5:1:E +5 1 E ``` -## First run +## Implementation Guidelines -Implement the Mars Rover as best as you can using TDD. +### First Implementation -### Example starting code +1. Use Test-Driven Development (TDD) +2. Start with the provided acceptance tests +3. Basic implementation example: ```typescript const rover = new Rover(); const finalPosition = rover.execute('5 5\n1 2 N\nLMLMLMLMM'); ``` -## Second run - -### Obstacles - -The grid may have obstacles. - -- The rover receives four lines of input: - - The first line defines the upper-right coordinates of the plateau. - - Example: ‘5:5’ - - The lower-left coordinates are always ‘0:0’. - - The second line contains the grid obstacles separated by a single space. - - Example ‘2:2 0:3 1:1’ - - The third line contains the rover’s starting position and direction. - - Example ‘1:2:N’ measn x=1, y=2 and Direction=North - - Assume that the square directly North from (x, y) is (x, y+1). - - The third line contains the sequence of commands to execute. - - Example: ‘LMLMLMLMM’ - - ‘L’ and ‘R’ makes the rover spin 90 degrees left or right respectively, without moving from its current spot. - - ‘M’ means move forward one grid point, and maintain the same heading. - -If a given sequence of commands encounters an obstacle, the rover moves up to the last possible point and reports the obstacle by prefixing O: to the position string that it returns. -For instance, 'O:1:1:N' would mean that the rover encountered an obstacle. - -#### Example - -```text -5:5 -0:3 2:2 -0:0 -MMMM -``` - -Given a grid with an obstacles at (0, 3) and (2, 2), input MMMM gives output O:0:2:N +### Refactoring Phase -## Third run +- Refactor using design patterns: + - Command Pattern + - State Pattern + - Strategy Pattern +- Reference: [Mars Rover Kata: Refactoring to Patterns](https://www.codurance.com/publications/2019/01/22/mars-rover-kata-refactoring-to-patterns) -Refactor the code you produced in the first run using design patterns, namely Command, State and Factory. +### TDD Rules -Additional reading after completing the exercise +1. ✅ Only write production code to pass a failing test +2. ✅ Write minimal test code to cause failure +3. ✅ Write minimal production code to pass the test diff --git a/README.md b/README.md index 92a4c6a..94ef9f5 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,12 @@ dotnet build dotnet test ``` +Or alternetively use the awsome TRX test reporting tool for the console + +```sh +dotnet test -l trx; trx +``` + ### Execute tests with coverage ```sh