Skip to content

Instantly share code, notes, and snippets.

@Chris--B
Last active August 29, 2015 14:01
Show Gist options
  • Save Chris--B/542943b66d9d234deac4 to your computer and use it in GitHub Desktop.
Save Chris--B/542943b66d9d234deac4 to your computer and use it in GitHub Desktop.
CS Connect Question of the Week: nth to last element of a singly linked list
#[deriving(Show)]
enum List<T> {
Node(T, ~List<T>),
Nil,
}
impl<T> List<T> {
fn len(&self) -> uint {
match *self {
Node(_, ref tail) => tail.len() + 1,
Nil => 0,
}
}
// Return a reference to the nth item.
fn get<'r>(&'r self, num: uint) -> &'r T {
match *self {
Node(_, ref tail) if num > 0 => tail.get(num - 1),
Node(ref thing, _) => &'r *thing,
Nil => fail!("Out of bounds! num = {}", num),
}
}
// Return a reference to the nth item, from the back
// of the list.
// As per the example, this is indexed at 1.
// That means 1 returns the last element,
// and list.len() returns the first.
fn getFromBack<'r>(&'r self, num: uint) -> &'r T {
// I don't think this was the expected solution.
self.get(self.len() - num)
}
}
#[test]
fn test_get_example_exhaustive() {
// This is the example used in the problem description.
// Encoded first as a Vec<int> and then as a List<int>.
let example = vec!(4, 9, 4, 2, 3, 1, 7, 8);
let list = Node(4, ~Node(9, ~Node(4, ~Node(2, ~Node(3, ~Node(1,
~Node(7, ~Node(8, ~Nil))))))));
for i in range(0, example.len()) {
assert_eq!(
example.get(i),
list.get(i));
}
}
#[test]
fn test_getFromBack_example_exhaustive() {
// This is the example used in the problem description.
// Encoded first as a Vec<int> and then as a List<int>.
let example = vec!(4, 9, 4, 2, 3, 1, 7, 8);
let list = Node(4, ~Node(9, ~Node(4, ~Node(2, ~Node(3, ~Node(1,
~Node(7, ~Node(8, ~Nil))))))));
for i in range(0, example.len()) {
assert_eq!(
example.get(example.len() - 1 - i),
list.getFromBack(i + 1)); // Indexed at 1.
}
}
#[test]
fn test_getFromBack_example_n_eq_3_returns_1() {
let list = Node(4, ~Node(9, ~Node(4, ~Node(2, ~Node(3, ~Node(1,
~Node(7, ~Node(8, ~Nil))))))));
assert_eq!(1, *list.getFromBack(3));
}
#[test]
#[should_fail]
fn test_getFromBack_0_is_out_of_bounds() {
let list = Node(4, ~Node(9, ~Node(4, ~Node(2, ~Node(3, ~Node(1,
~Node(7, ~Node(8, ~Nil))))))));
list.getFromBack(0);
}
#[test]
#[should_fail]
fn test_getFromBack_len_plus_1_is_out_of_bounds() {
let list = Node(4, ~Node(9, ~Node(4, ~Node(2, ~Node(3, ~Node(1,
~Node(7, ~Node(8, ~Nil))))))));
list.getFromBack(list.len() + 1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment