You've already forked comprehensive-rust
mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-06-23 09:16:44 +02:00
Comprehensive Rust v2 (#1073)
I've taken some work by @fw-immunant and others on the new organization of the course and condensed it into a form amenable to a text editor and some computational analysis. You can see the inputs in `course.py` but the interesting bits are the output: `outline.md` and `slides.md`. The idea is to break the course into more, smaller segments with exercises at the ends and breaks in between. So `outline.md` lists the segments, their duration, and sums those durations up per-day. It shows we're about an hour too long right now! There are more details of the segments in `slides.md`, or you can see mostly the same stuff in `course.py`. This now contains all of the content from the v1 course, ensuring both that we've covered everything and that we'll have somewhere to redirect every page. Fixes #1082. Fixes #1465. --------- Co-authored-by: Nicole LeGare <dlegare.1001@gmail.com> Co-authored-by: Martin Geisler <mgeisler@google.com>
This commit is contained in:
committed by
GitHub
parent
ea204774b6
commit
6d19292f16
132
src/smart-pointers/exercise.rs
Normal file
132
src/smart-pointers/exercise.rs
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright 2023 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// ANCHOR: solution
|
||||
// ANCHOR: types
|
||||
#[derive(Debug)]
|
||||
struct BinaryTreeNode<T: Ord + Copy> {
|
||||
value: T,
|
||||
left: BinaryTree<T>,
|
||||
right: BinaryTree<T>,
|
||||
}
|
||||
|
||||
/// A container storing a set of values, using a binary tree.
|
||||
///
|
||||
/// If the same value is added multiple times, it is only stored once.
|
||||
#[derive(Debug)]
|
||||
pub struct BinaryTree<T: Ord + Copy>(Option<Box<BinaryTreeNode<T>>>);
|
||||
// ANCHOR_END: types
|
||||
|
||||
impl<T: Ord + Copy> BinaryTree<T> {
|
||||
fn new() -> Self {
|
||||
Self(None)
|
||||
}
|
||||
|
||||
fn insert(&mut self, value: T) {
|
||||
match &mut self.0 {
|
||||
None => {
|
||||
self.0 = Some(Box::new(BinaryTreeNode {
|
||||
value,
|
||||
left: BinaryTree::new(),
|
||||
right: BinaryTree::new(),
|
||||
}));
|
||||
}
|
||||
Some(ref mut n) => {
|
||||
if value < n.value {
|
||||
n.left.insert(value);
|
||||
} else if value > n.value {
|
||||
n.right.insert(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn has(&self, value: T) -> bool {
|
||||
match &self.0 {
|
||||
None => false,
|
||||
Some(n) => {
|
||||
if value == n.value {
|
||||
true
|
||||
} else if value < n.value {
|
||||
n.left.has(value)
|
||||
} else {
|
||||
n.right.has(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
match &self.0 {
|
||||
None => 0,
|
||||
Some(n) => 1 + n.left.len() + n.right.len(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut tree = BinaryTree::new();
|
||||
tree.insert("foo");
|
||||
assert_eq!(tree.len(), 1);
|
||||
tree.insert("bar");
|
||||
assert!(tree.has("foo"));
|
||||
}
|
||||
|
||||
// ANCHOR: tests
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn len() {
|
||||
let mut tree = BinaryTree::new();
|
||||
assert_eq!(tree.len(), 0);
|
||||
tree.insert(2);
|
||||
assert_eq!(tree.len(), 1);
|
||||
tree.insert(1);
|
||||
assert_eq!(tree.len(), 2);
|
||||
tree.insert(2); // not a unique item
|
||||
assert_eq!(tree.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn has() {
|
||||
let mut tree = BinaryTree::new();
|
||||
fn check_has(tree: &BinaryTree<i32>, exp: &[bool]) {
|
||||
let got: Vec<bool> = (0..exp.len()).map(|i| tree.has(i as i32)).collect();
|
||||
assert_eq!(&got, exp);
|
||||
}
|
||||
|
||||
check_has(&tree, &[false, false, false, false, false]);
|
||||
tree.insert(0);
|
||||
check_has(&tree, &[true, false, false, false, false]);
|
||||
tree.insert(4);
|
||||
check_has(&tree, &[true, false, false, false, true]);
|
||||
tree.insert(4);
|
||||
check_has(&tree, &[true, false, false, false, true]);
|
||||
tree.insert(3);
|
||||
check_has(&tree, &[true, false, false, true, true]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unbalanced() {
|
||||
let mut tree = BinaryTree::new();
|
||||
for i in 0..100 {
|
||||
tree.insert(i);
|
||||
}
|
||||
assert_eq!(tree.len(), 100);
|
||||
assert!(tree.has(50));
|
||||
}
|
||||
}
|
||||
// ANCHOR_END: tests
|
Reference in New Issue
Block a user