Here's a problem inspired by Why Functional Programming Matters by John Hughes: find the most efficient way to archive digitized record albums onto DVD:
The problem is as follows:
Please solve these programming problems:
- Implement the standard greedy algorithm by writing a function
pack :: [(Album, Integer)] -> [DVD]
where
type Album = String
type DVD = [Album]
Decompose your solution into separate functions as described by Hughes.
- The result of a packing is a pure function of the order in which
albums appear on the list.
You can
improve a packing by using bubble search:
take the sorted list producing a new list using this algorithm:
repeat
probabilistically choose an item from the old list
remove that item from the old list and place it at the end of the
new list
until the old list is empty
Then you do the greedy packing algorithm on the perturbed list.
If the packing improves, the new ordering then becomes the basis for
further perturbations.
The probabilistic choice is parameterized by a probability p:
- Choose the first item with probability p
- Choose the second item with probability p×(1-p)
- Choose the ith item with probability p×(1-p)^i-1
- Choose the last item (in a list of length n) with probability
(1-p)^n-1
The problem is to implement packing by Bubble Search
Your function can take as an argument need an infinite list of random
numbers.
With p=0.45 and 10,000 iterations bubble search can consistently
produce packings of DVDs that are over 99.5% full.
Hints:
- Reuse as many of Hughes's combinators as possible.
- You'll need to plumb through an infinite list of random numbers.
Write new higher-order functions to help you do so.