Fall 2024 Rust Exam
Problem 1
Write function opposite
that accepts two parameters: a point A and a point B. Each is an xy-coordinate pair—a 2-tuple of f64
. It returns a point C that is like B but in the opposite direction from A. For example:
Problem 2
Write a main that accepts two unsigned integers as command-line arguments. It prints the equations of six arithmetic operations on the two numbers. For example:
$ ./main 3 5
3 + 5 = 8
3 - 5 = -2
3 * 5 = 15
3 / 5 = 0
3 % 5 = 3
3 ^ 5 = 243
$ ./main 3 5 3 + 5 = 8 3 - 5 = -2 3 * 5 = 15 3 / 5 = 0 3 % 5 = 3 3 ^ 5 = 243
Problem 3
Define the type Record
as a struct containing a String
name and a u32
score. Have the compiler automatically implement the Debug
trait.
Write function rank
that accepts two parameters: a borrowed Vec
of Record
, and a name as a borrowed string slice. It returns the named individual's rank amongst all the records as an Option<usize>
. The person with the highest score has rank 1. For example, suppose we have this vector of records:
let records = vec![
Record {name: "Elsif", score: 44},
Record {name: "Finny", score: 43},
Record {name: "Grada", score: 62}
];
let records = vec![ Record {name: "Elsif", score: 44}, Record {name: "Finny", score: 43}, Record {name: "Grada", score: 62} ];
Then we expect these results:
-
rank(&records, "Elsif")
→Some(2)
-
rank(&records, "Finny")
→Some(3)
-
rank(&records, "Grada")
→Some(1)
-
rank(&records, "Hattie")
→None
Problem 4
Imagine a game called Danger Farm played on a board of arbitrary width and height. In the bottommost row (row 0), there are 5 tiles of wheat on the left. In the next row (row 1), there are 5 tiles of wheat on the right. The wheat alternates between left and right for all remaining rows. Thistles cover the rest of the board. Any tile outside of the board is lava. Assume the board is at least 5 tiles wide. For example, here is a 12×5 board situated in some lava:
Write an enum Tile
with variants Wheat
, Thistle
, Lava
. Have the compiler automatically implement the Debug
, Eq
, and PartialEq
traits.
Write a function hit
that accepts two parameters: a board width and height as a pair of i32
, and a tile column and row as a pair of i32
. It returns the tile's type. For example:
-
hit(17, 3, 4, 0)
→Tile::Wheat
-
hit(17, 3, 5, 0)
→Tile::Thistle
-
hit(20, 30, 0, 1)
→Tile::Thistle
-
hit(20, 30, 19, 1)
→Tile::Wheat
-
hit(5, 20, 5, 0)
→Tile::Lava
Problem 5
A person's name is on several waiting lists. You want to know their best (minimal) position. Write function mindex
that accepts two parameters: a borrowed Vec
of waiting lists, and a name. Each name is a borrowed string slice, and each waiting list is a Vec
of names. Return an Option<usize>
indicating the index of the named individual's best position across all waiting lists. Suppose we have these waiting lists:
let lists = vec![
vec!["Joël", "Paola", "Buzz"],
vec!["Sally", "Buzz", "Paola", "Deanzel"],
vec!["Isaida", "Claire", "Joël"],
];
let lists = vec![ vec!["Joël", "Paola", "Buzz"], vec!["Sally", "Buzz", "Paola", "Deanzel"], vec!["Isaida", "Claire", "Joël"], ];
Then we have these minimal indices:
-
mindex(&lists, "Joël")
→Some(0)
-
mindex(&lists, "Paola")
→Some(1)
-
mindex(&lists, "Buzz")
→Some(1)
-
mindex(&lists, "Isaida")
→Some(0)
-
mindex(&lists, "Deanzel")
→Some(3)
-
mindex(&lists, "Vitali")
→None
Use iterators and higher-order functions. The Iterator.position
method is useful. Do not use loops.
Problem 6
Each subject in a taste test has sampled and scored \(n\) different foods. You want to decide how far two subjects are from one another. Write ndiff
that accepts two borrowed Vec
of food scores. Each score is a u32
. Return the sum of the absolute differences between corresponding scores. For example:
-
ndiff(&vec![5, 4, 6], &vec![6, 5, 7])
→3
-
ndiff(&vec![10, 10, 10, 10], &vec![0, 0, 0, 1])
→39
The u32::abs_diff
method is useful.
Problem 7
Write function to_ol
that accepts a borrowed Vec
of elements that implement the Display
trait. It returns as a String
the HTML form of the list. For example:
-
to_ol(&vec![53, 28])
→<ol> <li>53</li> <li>28</li> </ol>
<ol> <li>53</li> <li>28</li> </ol>
-
to_ol(&vec!["blue", "indigo", "violet"])
→<ol> <li>blue</li> <li>indigo</li> <li>violet</li> </ol>
<ol> <li>blue</li> <li>indigo</li> <li>violet</li> </ol>
Each line ends in a linebreak.
Problem 8
A trie is a tree data structure that efficiently stores strings with common prefixes. For example, this trie represents the words dust, duck, and do:
Each leaf node, prefixed by its ancestor letters, represents a word.
Your task is to model the nodes of a trie. Define a struct named Node
that has these two fields:
-
letter
, which is achar
-
children
, which is aVec
of child nodes
Implement these three subroutines for Node
:
-
Constructor function
new
that accepts two parameters: a letter and a vector of children. It assumes ownership of the vector. -
Method
collect
that returns aVec
ofString
. The vector contains all of the trie's strings in structural order. For the example, the returned vector contains dust, duck, and do. This method doesn't really do any work; it just defers tocollect_helper
. -
Method
collect_helper
that accepts two parameters: a prefix as a borrowed string slice, and a mutably borrowedVec
ofString
. It appends to the vector the node's strings—in structural order. Each string begins with the prefix.