Suppose a pile of change is present: quarters, nickels, dimes. And 51 exact cents are needed. How many ways can we make 51 cents?
With recursion, we can compute all possibilities. We can exhaustively search. We generate all possible ways to make change with coins. We print all results.
This may not be the most elegant solution possible. But it works. We introduce two functions: display (which displays coins) and change (which computes possibilities).
Display()
loops over all amounts (denominations) and counts coins that were added of these sizes.Seq.where
and Seq.length
functions to improve counting of coins in the display function.Change()
accepts 5 arguments. It sees if we have reached our goal amount (of 51 cents) and displays the result if we have.let display coins amounts = // Loop over all coin sizes. // ... Count all coins for each size. // Print the results to the screen. for amount in amounts do // Use where to filter coins by amount. // ... Return the length of the matching sequence. let count = Seq.where (fun x -> x = amount) coins |> Seq.length printfn "%d: %d" amount count printfn "" let rec change coins amounts highest sum goal = // If correct sum of coins, display them. // ... If not enough coins, loop through and add new coins. if sum = goal then display coins amounts elif sum < goal then // Loop over possible coin sizes. for value in amounts do // Only add larger coins. if value >= highest then // Place new coin at the start of the list (the head) and continue. let copy = value :: coins change copy amounts value (sum + value) goal // Begin with these coins. let coins = [] // Specify the amounts. let amounts = [1; 5; 10; 25; 50] // Call recursive function. change coins amounts 0 0 511: 51 5: 0 10: 0 25: 0 50: 0 1: 46 5: 1 10: 0 25: 0 50: 0 1: 41 5: 2 10: 0 25: 0 50: 0 ... 1: 1 5: 0 10: 0 25: 2 50: 0 1: 1 5: 0 10: 0 25: 0 50: 1
The change call in the body of the for
-loop is a recursive call. We keep track of the sum of our change with an addition.
error FS0039: The value or constructor 'change' is not defined
If you are learning F# you are probably familiar with the Structure
and Interpretation of Computer Programs. This example was based on a puzzle in SICP.
With recursion and appropriate logic we can solve many logic puzzles. Details are often a point of failure. And in puzzles like these there are many details.