Skip to content

Commit 929fbcc

Browse files
Finish first pass on updating exercises
1 parent 0036292 commit 929fbcc

32 files changed

+1560
-301
lines changed

courses/comprehensive_rust_training/140_smart_pointers.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ Smart Pointers
3939
.. include:: 140_smart_pointers/01_box.rst
4040
.. include:: 140_smart_pointers/02_rc.rst
4141
.. include:: 140_smart_pointers/03_trait_objects.rst
42-
.. include:: 140_smart_pointers/04_exercise.rst
42+
.. include:: 140_smart_pointers/99_lab.rst

courses/comprehensive_rust_training/140_smart_pointers/04_exercise.rst

-26
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
=======================
2+
Exercise: Binary Tree
3+
=======================
4+
5+
-----------------------
6+
Binary Tree Problem
7+
-----------------------
8+
9+
A binary tree is a tree-type data structure where every node has two
10+
children (left and right). We will create a tree where each node stores
11+
a value. For a given node N, all nodes in a N's left subtree contain
12+
smaller values, and all nodes in N's right subtree will contain larger
13+
values.
14+
15+
.. container:: source_include 140_smart_pointers/src/140_smart_pointers.rs :start-after://ANCHOR-types :end-before://ANCHOR-solution :code:rust
16+
17+
-----------------------
18+
Binary Tree Main
19+
-----------------------
20+
21+
Implement :rust:`new`, :rust:`insert`, :rust:`len`, and :rust:`has` for :rust:`Subtree`.
22+
23+
.. container:: source_include 140_smart_pointers/src/140_smart_pointers.rs :start-after://ANCHOR-main :end-before://ANCHOR-tests :code:rust
24+
25+
-----------------------
26+
Binary Tree Solution
27+
-----------------------
28+
29+
.. container:: source_include 140_smart_pointers/src/140_smart_pointers.rs :start-after://ANCHOR-solution :end-before://ANCHOR-main :code:rust
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// Copyright 2023 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
//ANCHOR-types
16+
use std::cmp::Ordering;
17+
18+
/// A node in the binary tree.
19+
#[derive(Debug)]
20+
struct Node<T: Ord> {
21+
value: T,
22+
left: Subtree<T>,
23+
right: Subtree<T>,
24+
}
25+
26+
/// A possibly-empty subtree.
27+
#[derive(Debug)]
28+
struct Subtree<T: Ord>(Option<Box<Node<T>>>);
29+
30+
/// A container storing a set of values, using a binary tree.
31+
///
32+
/// If the same value is added multiple times, it is only stored once.
33+
#[derive(Debug)]
34+
pub struct BinaryTree<T: Ord> {
35+
root: Subtree<T>,
36+
}
37+
38+
impl<T: Ord> BinaryTree<T> {
39+
fn new() -> Self {
40+
Self { root: Subtree::new() }
41+
}
42+
43+
fn insert(&mut self, value: T) {
44+
self.root.insert(value);
45+
}
46+
47+
fn has(&self, value: &T) -> bool {
48+
self.root.has(value)
49+
}
50+
51+
fn len(&self) -> usize {
52+
self.root.len()
53+
}
54+
}
55+
56+
//ANCHOR-solution
57+
impl<T: Ord> Subtree<T> {
58+
fn new() -> Self {
59+
Self(None)
60+
}
61+
62+
fn insert(&mut self, value: T) {
63+
match &mut self.0 {
64+
None => self.0 = Some(Box::new(Node::new(value))),
65+
Some(n) => match value.cmp(&n.value) {
66+
Ordering::Less => n.left.insert(value),
67+
Ordering::Equal => {}
68+
Ordering::Greater => n.right.insert(value),
69+
},
70+
}
71+
}
72+
73+
fn has(&self, value: &T) -> bool {
74+
match &self.0 {
75+
None => false,
76+
Some(n) => match value.cmp(&n.value) {
77+
Ordering::Less => n.left.has(value),
78+
Ordering::Equal => true,
79+
Ordering::Greater => n.right.has(value),
80+
},
81+
}
82+
}
83+
84+
fn len(&self) -> usize {
85+
match &self.0 {
86+
None => 0,
87+
Some(n) => 1 + n.left.len() + n.right.len(),
88+
}
89+
}
90+
}
91+
92+
impl<T: Ord> Node<T> {
93+
fn new(value: T) -> Self {
94+
Self { value, left: Subtree::new(), right: Subtree::new() }
95+
}
96+
}
97+
98+
//ANCHOR-main
99+
fn main() {
100+
let mut tree = BinaryTree::new();
101+
tree.insert("foo");
102+
assert_eq!(tree.len(), 1);
103+
tree.insert("bar");
104+
assert!(tree.has(&"foo"));
105+
}
106+
107+
//ANCHOR-tests
108+
#[cfg(test)]
109+
mod tests {
110+
use super::*;
111+
112+
#[test]
113+
fn len() {
114+
let mut tree = BinaryTree::new();
115+
assert_eq!(tree.len(), 0);
116+
tree.insert(2);
117+
assert_eq!(tree.len(), 1);
118+
tree.insert(1);
119+
assert_eq!(tree.len(), 2);
120+
tree.insert(2); // not a unique item
121+
assert_eq!(tree.len(), 2);
122+
}
123+
124+
#[test]
125+
fn has() {
126+
let mut tree = BinaryTree::new();
127+
fn check_has(tree: &BinaryTree<i32>, exp: &[bool]) {
128+
let got: Vec<bool> =
129+
(0..exp.len()).map(|i| tree.has(&(i as i32))).collect();
130+
assert_eq!(&got, exp);
131+
}
132+
133+
check_has(&tree, &[false, false, false, false, false]);
134+
tree.insert(0);
135+
check_has(&tree, &[true, false, false, false, false]);
136+
tree.insert(4);
137+
check_has(&tree, &[true, false, false, false, true]);
138+
tree.insert(4);
139+
check_has(&tree, &[true, false, false, false, true]);
140+
tree.insert(3);
141+
check_has(&tree, &[true, false, false, true, true]);
142+
}
143+
144+
#[test]
145+
fn unbalanced() {
146+
let mut tree = BinaryTree::new();
147+
for i in 0..100 {
148+
tree.insert(i);
149+
}
150+
assert_eq!(tree.len(), 100);
151+
assert!(tree.has(&50));
152+
}
153+
}

courses/comprehensive_rust_training/160_lifetimes.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ Lifetimes
3939
.. include:: 160_lifetimes/01_lifetime_annotations.rst
4040
.. include:: 160_lifetimes/02_lifetime_elision.rst
4141
.. include:: 160_lifetimes/03_struct_lifetimes.rst
42-
.. include:: 160_lifetimes/04_exercise.rst
42+
.. include:: 160_lifetimes/99_lab.rst

courses/comprehensive_rust_training/160_lifetimes/04_exercise.rst

-111
This file was deleted.

0 commit comments

Comments
 (0)