Skip to content

Commit 7fb4ac6

Browse files
committed
Replace bst searching exercise with ring buffer exercise
1 parent 4746e3e commit 7fb4ac6

File tree

7 files changed

+76
-139
lines changed

7 files changed

+76
-139
lines changed

Data_Structures_Answers.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
Add your answers to the questions below.
22

3-
1. What is the runtime complexity of your `depth_first_for_each` method?
3+
1. What is the runtime complexity of your ring buffer's `append` method?
44

5-
2. What is the space complexity of your `depth_first_for_each` function?
5+
2. What is the space complexity of your ring buffer's `append` function?
66

7-
3. What is the runtime complexity of your `breadth_first_for_each` method?
7+
3. What is the runtime complexity of your ring buffer's `get` method?
88

9-
4. What is the space complexity of your `breadth_first_for_each` method?
9+
4. What is the space complexity of your ring buffer's `get` method?
1010

1111

1212
5. What is the runtime complexity of the provided code in `names.py`?

README.md

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,33 @@ This Sprint Challenge is split into three parts:
2626

2727
### Minimum Viable Product
2828

29+
#### Task 1. Implement a Ring Buffer Data Structure
2930

30-
#### Task 1. Implement Depth-First or Breadth-First Traversal on the Binary Search Tree Class
31+
A ring buffer is a non-growable buffer with a fixed size. When the ring buffer is full and a new element is inserted, the oldest element in the ring buffer is overwritten with the newest element. This kind of data structure is very useful for use cases such as storing logs and history information, where you typically want to store information up until it reaches a certain age, after which you don't care about it anymore and don't mind seeing it overwritten by newer data.
3132

32-
Navigate into the `search` directory. Inside, you'll see the `binary-search-tree.py` file with a complete implementation of the binary search tree class. Your first task is to implement either `depth_first_for_each` or `breadth_first_for_each` on the `BinarySearchTree` class:
33+
Implement this behavior in the RingBuffer class. RingBuffer has two methods, `append` and `get`. The `append` method adds elements to the buffer. The `get` method returns all of the elements in the buffer ordered from oldest to newest. In other words, least-recently added elements first, then most-recently added elements.
3334

34-
* `depth_first_for_each(cb)` receives an anonymous function as a parameter. It should then execute the anonymous function on each node in the tree in [depth-first](https://en.wikipedia.org/wiki/Depth-first_search) order. Your task is to implement the logic to traverse the tree in depth-first pre-order fashion (as opposed to in-order or post-order). Note that the pseudocode showcased on the Wikipedia article traverses the tree in-order.
35+
For example:
3536

36-
* Remember that the anonymous function is supplied by the caller of the method. All you have to do is ensure that the anonymous function is being called on each tree node in the desired order.
37-
38-
_HINT_: In order to achieve depth-first order, you'll probably want to utilize a Stack data structure.
37+
```python
38+
buffer = RingBuffer(3)
3939

40-
* Run `python test_depth_first_search.py` to test your depth-first search implementation.
40+
buffer.append('a')
41+
buffer.append('b')
42+
buffer.append('c')
4143

42-
* `breadth_first_for_each(cb)` receives a callback function as a parameter. It should then execute the anonymous function on each node in the tree in [breadth-first](https://en.wikipedia.org/wiki/Breadth-first_search) order. Your task is to implement the logic to traverse the tree in left-to-right breadth-first fashion.
43-
44-
* Remember that the anonymous function is supplied by the caller of the method. All you have to do is ensure that the anonymous function is being called on each tree node in the desired order.
45-
46-
_HINT_: In order to achieve breadth-first order, you'll probably want to utilize a Queue data structure.
44+
buffer.get() # should return ['a', 'b', 'c']
4745

48-
* Run `python test_breadth_first_search.py` to test your breadth-first search implementation.
46+
# 'd' overwrites the oldest value in the ring buffer, which is 'a'
47+
buffer.append('d')
4948

50-
> Note that in Python, anonymous functions are referred to as "lambda functions". When passing in an anonymous function as input to either `depth_first_for_each` or `breadth_first_for_each`, you'll want to define them as lambda functions. For more information on lambda functions, check out this documentation: [https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions](https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions)
49+
buffer.get() # should return ['d', 'b', 'c']
5150

52-
> Note that it is not your job to worry about what the callback function being passed in is doing. That is up to the user of your traversal method. All you care about when implementing the traversal method is to call the passed-in callback in either depth-first or breadth-first order, depending on which traversal method you're implementing.
51+
buffer.append('e')
52+
buffer.append('f')
5353

54+
buffer.get() # should return ['d', 'e', 'f']
55+
```
5456

5557
#### Task 2. Runtime Optimization
5658

@@ -60,7 +62,7 @@ Six seconds is an eternity so you've been tasked with speeding up the code. Can
6062

6163
(Hint: You might try importing a data structure you built during the week)
6264

63-
#### Task 3. Analyze some runtimes
65+
#### Task 3. Analyze Some Runtimes
6466

6567
Open up the `Data_Structures_Answers.md` file. This is where you'll jot down your answers for the runtimes of the functions you just implemented. If you implemented depth-first traversal, just answer the questions pertaining to the depth-first traversal algorithm. If you implemented breadth-first traversal, just answer the questions pertaining to breadth-first traversal.
6668

@@ -75,26 +77,26 @@ Also, include the runtime and space complexities of the original code and your o
7577

7678
### Rubric
7779

78-
#### SEARCH
80+
#### Ring Buffer
7981

80-
- DFS or BFS pass tests: 10 points
82+
- Ring buffer implementation passes the tests: 10 points total
8183

82-
#### NAMES
84+
#### Names
8385

84-
- Optimize with an O(n log n) runtime solution: 8 points
85-
- Optimize with an O(n) runtime solution: 10 points
86+
- Optimize with an O(n log n) runtime solution: 8 points total
87+
- Optimize with an O(n) runtime solution: 10 points total
8688

87-
#### COMPLEXITY
89+
#### Complexity
8890

89-
- One point each: 8 points
91+
- One point each: 8 points total
9092

91-
#### STRETCH
93+
#### Stretch
9294

9395
- Both DFS and BFS pass tests: 2 points
9496
- `names.py` is optimized with sub-quadratic runtime complexity and tightly constrained linear space complexity: 2 points
9597

9698

97-
#### GRADING
99+
#### Grading
98100

99101
* *3*: 28+
100102
* *2*: 20-27

ring_buffer/ring_buffer.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class RingBuffer:
2+
def __init__(self, capacity):
3+
self.capacity = capacity
4+
self.current = 0
5+
self.storage = [None]*capacity
6+
7+
def append(self, item):
8+
pass
9+
10+
def get(self):
11+
pass

ring_buffer/test_ring_buffer.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import unittest
2+
from ring_buffer import RingBuffer
3+
4+
class RingBufferTests(unittest.TestCase):
5+
def setUp(self):
6+
self.buffer = RingBuffer(5)
7+
8+
def test_ring_buffer(self):
9+
self.assertEqual(len(self.buffer.storage), 5)
10+
11+
self.buffer.append('a')
12+
self.buffer.append('b')
13+
self.buffer.append('c')
14+
self.buffer.append('d')
15+
self.assertEqual(len(self.buffer.storage), 5)
16+
self.assertEqual(self.buffer.get(), ['a', 'b', 'c', 'd'])
17+
18+
self.buffer.append('e')
19+
self.assertEqual(len(self.buffer.storage), 5)
20+
self.assertEqual(self.buffer.get(), ['a', 'b', 'c', 'd', 'e'])
21+
22+
self.buffer.append('f')
23+
self.assertEqual(len(self.buffer.storage), 5)
24+
self.assertEqual(self.buffer.get(), ['f', 'b', 'c', 'd', 'e'])
25+
26+
self.buffer.append('g')
27+
self.buffer.append('h')
28+
self.buffer.append('i')
29+
self.assertEqual(len(self.buffer.storage), 5)
30+
self.assertEqual(self.buffer.get(), ['f', 'g', 'h', 'i', 'e'])
31+
32+
33+
if __name__ == '__main__':
34+
unittest.main()

search/binary_search_tree.py

Lines changed: 0 additions & 49 deletions
This file was deleted.

search/test_breadth_first_search.py

Lines changed: 0 additions & 31 deletions
This file was deleted.

search/test_depth_first_search.py

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)