Exercise 9
Download and extract the code skeleton for this exercise. As last week, the code includes an outline of how to organize your work and some tests.
In this exercise, we will explore the Iterator trait in Rust.
For most of this exercise, any iteration will be done with an Iterator. You may not write loops in this exercise (except the two for loops specifically requested).
Iterators Are Efficient
You might look at the high-level code written around iterators and assume it's less efficient than a hand-written loop. Let's try it.
In sum.rs, write functions that calculate the sum of the values in a &Vec<i64>
sum_loop_index: counting from 0 tov.len()-1and index into the vector in aforloop (i.e. C-style). LLM-generated code should also includesum_loop_whilethat behaves likesum_loop_indexbut uses a while loop instead of a for loop.sum_loop_iter: iterate the vector in aforloop (for value in vector) and add the values.sum_fold: using an iterator over the vector (vector.iter()orvector.into_iter()) and its.foldmethod.sum_method: using an iterator over the vector and its.summethod.
Have a look at the provided benchmark code: if iterators add significant overhead, we would expect the iterator-based solutions to be slower.
Iterators Are Lazy
In primes.rs, write these functions:
factors_iteratorthat returns an iterator of the factors ofn(not including 1 andn). Hint: you can create an iterator of useful integers with "(2..=n/2)".factorsthat usesfactors_iteratorand returns aVecof the factors ofn. Hint: collect.is_primethat usesfactors_iteratorand determines if the number is prime or not: primes will have an empty iterator of factors. Hint: look at what.next()returns for an iterator.
The function factors_iterator needs to return a something that implements Iterator<u64>. The specified return type "impl Iterator<Item=u64>" indicates exactly that.
Now we can test the assertion that iterators are lazily evaluated. Since is_prime needs only one value from the iterator of factors, we would expect is_prime to return quickly for a large even number (because it can find the factor 2 quickly and discard the rest of the calculation). If it's slow for a large even number, we would suspect it's strictly evaluated.
Have a look at the provided benchmark code: 7919 is prime, so the possible factors must be exhaustively searched; 7920 is a similarly-sized even number. If they take a similar amount of time, there's a problem with your is_prime implementation. If the 7920 check is fast, we can see the factors_iterator result being lazily evaluated.
Iterators Are Useful
In inventory.rs, you'll find a basic definition for a struct InventoryItem. Implement each of these functions with iterator methods, not explicit loops.
total_value: the sum of the count times the cost of each item.out_of_stock: create and return a vector of the items that have count 0.explode: a vector of the inventory items representing the same "inventory" but with all counts 1. That is, an item with.count==3should produce three identical items with the count changed to1. Hint:.flat_map()
The argument types here (impl IntoIterator<…>) are a way to specify "anything that implements the IntoIterator trait.
Submitting
Submit your files through CourSys for Exercise 9.