Unable to understand how this recursive function evaluates - recursion

Please help me understand how the following code always returns the smallest value in the array. I tried moving position of 3 but it always manages to return it irrespective of the position of it in the array.
let myA = [12,3,8,5]
let myN = 4
function F4(A,N)
{
if(N==1){
return A[0]
}
if(F4(A,N-1) < A[N-1]){
return F4(A,N-1)
}
return A[N-1]
}
console.log(F4(myA,myN))

This is quite tricky to get an intuition for. It's also quite important that you learn the process for tackling this type of problem rather than simply be told the answer.
If we take a first view of the code with a few comments and named variables it looks like this:
let myA = [12,3,8,5];
let myN = myA.length;
function F4(A, N) {
// if (once) there is only one element in the array "A", then it must be the minimum, do not recurse
if (N === 1){
return A[0]
}
const valueFromArrayLessLastEl = F4(A,N-1); // Goes 'into' array
const valueOfLastElement = A[N-1];
console.log(valueFromArrayLessLastEl, valueOfLastElement);
// note that the recursion happens before min(a, b) is evaluated so array is evaluated from the start
if (valueFromArrayLessLastEl < valueOfLastElement) {
return valueFromArrayLessLastEl;
}
return valueOfLastElement;
}
console.log(F4(myA, myN))
and produces
12 3 // recursed all the way down
3 8 // stepping back up with result from most inner/lowest recursion
3 5
3
but in order to gain insight it is vital that you approach the problem by considering the simplest cases and expand from there. What happens if we write the code for the cases of N = 1 and N = 2:
// trivially take N=1
function F1(A) {
return A[0];
}
// take N=2
function F2(A) {
const f1Val = F1(A); // N-1 = 1
const lastVal = A[1];
// return the minimum of the first element and the 2nd or last element
if (f1Val < lastVal) {
return f1Val;
}
return lastVal;
}
Please note that the array is not being modified, I speak as though it is because the value of N is decremented on each recursion.
With myA = [12, 3, 8, 5] F1 will always return 12. F2 will compare this value 12 with 3, the nth-1 element's value, and return the minimum.
If you can build on this to work out what F3 would do then you can extrapolate from there.
Play around with this, reordering the values in myA, but crucially look at the output as you increase N from 1 to 4.
As a side note: by moving the recursive call F4(A,N-1) to a local constant I've prevented it being called twice with the same values.

Related

Generate sequence using previous values

I'm learning functional programming with F#, and I want to write a function that will generate a sequence for me.
There is a some predetermined function for transforming a value, and in the function I need to write there should be two inputs - the starting value and the length of the sequence. Sequence starts with the initial value, and each following item is a result of applying the transforming function to the previous value in the sequence.
In C# I would normally write something like that:
public static IEnumerable<double> GenerateSequence(double startingValue, int n)
{
double TransformValue(double x) => x * 0.9 + 2;
yield return startingValue;
var returnValue = startingValue;
for (var i = 1; i < n; i++)
{
returnValue = TransformValue(returnValue);
yield return returnValue;
}
}
As I tried to translate this function to F#, I made this:
let GenerateSequence startingValue n =
let transformValue x =
x * 0.9 + 2.0
seq {
let rec repeatableFunction value n =
if n = 1 then
transformValue value
else
repeatableFunction (transformValue value) (n-1)
yield startingValue
for i in [1..n-1] do
yield repeatableFunction startingValue i
}
There are two obvious problems with this implementation.
First is that because I tried to avoid making a mutable value (analogy of returnValue variable in C# implementation), I didn't reuse values of former computations while generating sequence. This means that for the 100th element of the sequence I have to make additional 99 calls of the transformValue function instead of just one (as I did in C# implementation). This reeks with extremely bad performance.
Second is that the whole function does not seem to be written in accordance with Functional Programming. I am pretty sure that there are more elegant and compact implementation. I suspect that Seq.fold or List.fold or something like that should have been used here, but I'm still not able to grasp how to effectively use them.
So the question is: how to re-write the GenerateSequence function in F# so it would be in Functional Programming style and have a better performance?
Any other advice would also be welcomed.
The answer from #rmunn shows a rather nice solution using unfold. I think there are other two options worth considering, which are actually just using a mutable variable and using a recursive sequence expression. The choice is probably a matter of personal preference. The two other options look like this:
let generateSequenceMutable startingValue n = seq {
let transformValue x = x * 0.9 + 2.0
let mutable returnValue = startingValue
for i in 1 .. n do
yield returnValue
returnValue <- transformValue returnValue }
let generateSequenceRecursive startingValue n =
let transformValue x = x * 0.9 + 2.0
let rec loop value i = seq {
if i < n then
yield value
yield! loop (transformValue value) (i + 1) }
loop startingValue 0
I modified your logic slightly so that I do not have to yield twice - I just do one more step of the iteration and yield before updating the value. This makes the generateSequenceMutable function quite straightforward and easy to understand. The generateSequenceRecursive implements the same logic using recursion and is also fairly nice, but I find it a bit less clear.
If you wanted to use one of these versions and generate an infinite sequence from which you can then take as many elements as you need, you can just change for to while in the first case or remove the if in the second case:
let generateSequenceMutable startingValue n = seq {
let transformValue x = x * 0.9 + 2.0
let mutable returnValue = startingValue
while true do
yield returnValue
returnValue <- transformValue returnValue }
let generateSequenceRecursive startingValue n =
let transformValue x = x * 0.9 + 2.0
let rec loop value i = seq {
yield value
yield! loop (transformValue value) (i + 1) }
loop startingValue 0
If I was writing this, I'd probably go either with the mutable variable or with unfold. Mutation may be "generally evil" but in this case, it is a localized mutable variable that is not breaking referential transparency in any way, so I don't think it's harmful.
Your description of the problem was excellent: "Sequence starts with the initial value, and each following item is a result of applying the transforming function to the previous value in the sequence."
That is a perfect description of the Seq.unfold method. It takes two parameters: the initial state and a transformation function, and returns a sequence where each value is calculated from the previous state. There are a few subtleties involved in using Seq.unfold which the rather terse documentation may not explain very well:
Seq.unfold expects the transformation function, which I'll call f from now on, to return an option. It should return None if the sequence should end, or Some (...) if there's another value left in the sequence. You can create infinite sequences this way if you never return None; infinite sequences are perfectly fine since F# evaluates sequences lazily, but you do need to be careful not to ever loop over the entirely of an infinite sequence. :-)
Seq.unfold also expects that if f returns Some (...), it will return not just the next value, but a tuple of the next value and the next state. This is shown in the Fibonacci example in the documentation, where the state is actually a tuple of the current value and the previous value, which will be used to calculate the next value shown. The documentation example doesn't make that very clear, so here's what I think is a better example:
let infiniteFibonacci = (0,1) |> Seq.unfold (fun (a,b) ->
// a is the value produced *two* iterations ago, b is previous value
let c = a+b
Some (c, (b,c))
)
infiniteFibonacci |> Seq.take 5 |> List.ofSeq // Returns [1; 2; 3; 5; 8]
let fib = seq {
yield 0
yield 1
yield! infiniteFibonacci
}
fib |> Seq.take 7 |> List.ofSeq // Returns [0; 1; 1; 2; 3; 5; 8]
And to get back to your GenerateSequence question, I would write it like this:
let GenerateSequence startingValue n =
let transformValue x =
let result = x * 0.9 + 2.0
Some (result, result)
startingValue |> Seq.unfold transformValue |> Seq.take n
Or if you need to include the starting value in the sequence:
let GenerateSequence startingValue n =
let transformValue x =
let result = x * 0.9 + 2.0
Some (result, result)
let rest = startingValue |> Seq.unfold transformValue |> Seq.take n
Seq.append (Seq.singleton startingValue) rest
The difference between Seq.fold and Seq.unfold
The easiest way to remember whether you want to use Seq.fold or Seq.unfold is to ask yourself which of these two statements is true:
I have a list (or array, or sequence) of items, and I want to produce a single result value by running a calculation repeatedly on pairs of items in the list. For example, I want to take the product of this whole series of numbers. This is a fold operation: I take a long list and "compress" it (so to speak) until it's a single value.
I have a single starting value and a function to produce the next value from the current value, and I want to end up with a list (or sequence, or array) of values. This is an unfold operation: I take a small starting value and "expand" it (so to speak) until it's a whole list of values.

Unique array of random numbers using functional programming

I'm trying to write some code in a functional paradigm for practice. There is one case I'm having some problems wrapping my head around. I am trying to create an array of 5 unique integers from 1, 100. I have been able to solve this without using functional programming:
let uniqueArray = [];
while (uniqueArray.length< 5) {
const newNumber = getRandom1to100();
if (uniqueArray.indexOf(newNumber) < 0) {
uniqueArray.push(newNumber)
}
}
I have access to lodash so I can use that. I was thinking along the lines of:
const uniqueArray = [
getRandom1to100(),
getRandom1to100(),
getRandom1to100(),
getRandom1to100(),
getRandom1to100()
].map((currentVal, index, array) => {
return array.indexOf(currentVal) > -1 ? getRandom1to100 : currentVal;
});
But this obviously wouldn't work because it will always return true because the index is going to be in the array (with more work I could remove that defect) but more importantly it doesn't check for a second time that all values are unique. However, I'm not quite sure how to functionaly mimic a while loop.
Here's an example in OCaml, the key point is that you use accumulators and recursion.
let make () =
Random.self_init ();
let rec make_list prev current max accum =
let number = Random.int 100 in
if current = max then accum
else begin
if number <> prev
then (number + prev) :: make_list number (current + 1) max accum
else accum
end
in
make_list 0 0 5 [] |> Array.of_list
This won't guarantee that the array will be unique, since its only checking by the previous. You could fix that by hiding a hashtable in the closure between make and make_list and doing a constant time lookup.
Here is a stream-based Python approach.
Python's version of a lazy stream is a generator. They can be produced in various ways, including by something which looks like a function definition but uses the key word yield rather than return. For example:
import random
def randNums(a,b):
while True:
yield random.randint(a,b)
Normally generators are used in for-loops but this last generator has an infinite loop hence would hang if you try to iterate over it. Instead, you can use the built-in function next() to get the next item in the string. It is convenient to write a function which works something like Haskell's take:
def take(n,stream):
items = []
for i in range(n):
try:
items.append(next(stream))
except StopIteration:
return items
return items
In Python StopIteration is raised when a generator is exhausted. If this happens before n items, this code just returns however much has been generated, so perhaps I should call it takeAtMost. If you ditch the error-handling then it will crash if there are not enough items -- which maybe you want. In any event, this is used like:
>>> s = randNums(1,10)
>>> take(5,s)
[6, 6, 8, 7, 2]
of course, this allows for repeats.
To make things unique (and to do so in a functional way) we can write a function which takes a stream as input and returns a stream consisting of unique items as output:
def unique(stream):
def f(s):
items = set()
while True:
try:
x = next(s)
if not x in items:
items.add(x)
yield x
except StopIteration:
raise StopIteration
return f(stream)
this creates an stream in a closure that contains a set which can keep track of items that have been seen, only yielding items which are unique. Here I am passing on any StopIteration exception. If the underlying generator has no more elements then there are no more unique elements. I am not 100% sure if I need to explicitly pass on the exception -- (it might happen automatically) but it seems clean to do so.
Used like this:
>>> take(5,unique(randNums(1,10)))
[7, 2, 5, 1, 6]
take(10,unique(randNums(1,10))) will yield a random permutation of 1-10. take(11,unique(randNums(1,10))) will never terminate.
This is a very good question. It's actually quite common. It's even sometimes asked as an interview question.
Here's my solution to generating 5 integers from 0 to 100.
let rec take lst n =
if n = 0 then []
else
match lst with
| [] -> []
| x :: xs -> x :: take xs (n-1)
let shuffle d =
let nd = List.map (fun c -> (Random.bits (), c)) d in
let sond = List.sort compare nd in
List.map snd sond
let rec range a b =
if a >= b then []
else a :: range (a+1) b;;
let _ =
print_endline
(String.concat "\t" ("5 random integers:" :: List.map string_of_int (take (shuffle (range 0 101)) 5)))
How's this:
const addUnique = (ar) => {
const el = getRandom1to100();
return ar.includes(el) ? ar : ar.concat([el])
}
const uniqueArray = (numberOfElements, baseArray) => {
if (numberOfElements < baseArray.length) throw 'invalid input'
return baseArray.length === numberOfElements ? baseArray : uniqueArray(numberOfElements, addUnique(baseArray))
}
const myArray = uniqueArray(5, [])

Write a recursive function that returns a stack of Fibonacci sequence

My teacher just asked this question in the exam and I have no idea where to go on.
More details, the prototype of function is given as:
stack<int> Fibonacci_sequence(int n); //fibonacci numbers count up to n
The point is this function is recursive and it should return a stack data type. In my opinion I don't think this is a possible thing to do, but my teacher asked it!!
P.s: sorry, my language is C++
function stack<int> Fibonacci_sequence(int n) {
if n == 0 {
var a stack<int>;
a.push(0);
return a
} else if n == 1 {
var a stack<int>;
a.push(0);
a.push(1);
return a
} else
var temp int;
var seq int;
seq = Fibonacci_sequence(n-1);
temp = seq.pop;
seq.push(temp);
seq.push(temp);
//above: the top element of the stack must be duplicated because it
//is popped off in the process of calculating the sum.
seq.push(seq.pop()+Fibonacci_sequence(n-2).pop());
return seq
}
}
Above is a function that does just that, written in pseudo code because you did not specify a language. Hopefully this helps, it was fun to come up with! Thanks for the interesting question.
Since you didn't specify a language, and you specified it's an exam, here it is in Ruby. Ruby provides stack operations for arrays, but I'm only using push and pop operations in the following so you should be able to easily translate it to the language of your choice.
def fib(n) # no explicit return type, since everything's an object in Ruby
fail "negative argument not allowed" if n < 0
if n > 1
stack = fib(n - 1)
# grab the last two values...
f_n_1 = stack.pop
f_n_2 = stack.pop
# ...and use them to calculate the next.
# The value of this expression is the resulting stack, return it
return stack.push(f_n_2).push(f_n_1).push(f_n_1 + f_n_2)
elsif n == 1
return fib(0).push(1)
else
return [].push(0)
end
end
p fib(10) # => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
You may have to translate this to the language of your exam, but that's appropriate.
Here is my C++ code based on #Elliot pseudo, and it got errors, I specified these errors in the code. And I just figure out that pop() doesn't return a value, I'm gonna fix this.
stack<int> Fibonacci_sequence(int n)
{
if (n == 0) {
stack<int> a;
a.push(0);
return a;
}
else if (n == 1) {
stack<int> a;
a.push(0);
a.push(1);
return a;
}
else
{
int temp;
temp = Fibonacci_sequence(n - 1).pop(); //error C2440: '=': cannot convert from 'void' to 'int'
Fibonacci_sequence(n - 1).push(temp);
Fibonacci_sequence(n - 1).push(temp);
//above: the top element of the stack must be duplicated because it
//is popped off in the process of calculating the sum.
return Fibonacci_sequence(n - 1).push(Fibonacci_sequence(n - 1).pop() + Fibonacci_sequence(n - 2).pop());//error C2186: '+': illegal operand of type 'void'
}
}

Int list to unit type

I am looking for a function for : int * int * (int -> unit) -> unit. I need this to print a list of numbers. To be more specific, I have a function f num = print ((Int.toString num)^"\n"). So far, I have this:
fun for(from,to,f)=
if from=to then [f(to)]
else f(from)::for(from+1,to,f)
which gives me a return type of unit list. How can I call for function without appending to earlier result?
The () you want to return is the () from the last call to f - that is, the call from the then branch.
Generally speaking, whenever you want to do two things, and only return the result of the second thing, you use the following syntax:
(thing1;thing2)
For example:
(print "foo\n"; 2 + 3);
Would print out the string "foo\n", and then return 5.
So now, let's look at the two branches of your code.
fun for (from,to,f) = if from = to
then ...
else ...
In the then branch, we simply call f on to. f already returns (), so we don't do anything more with the result:
fun for (from,to,f) = if from = to
then f to
else ...
The else branch is slightly more complicated. We want to call f on from, and then make a recursive call. The return type of the recursive call is unit, so that's what we want to return:
fun for (from,to,f) = if from = to
then f to
else (f from;for (from+1,to,f));
Another thing: What happens if you do this?
for (4,3,f)

iterative version of easy recursive algorithm

I have a quite simple question, I think.
I've got this problem, which can be solved very easily with a recursive function, but which I wasn't able to solve iteratively.
Suppose you have any boolean matrix, like:
M:
111011111110
110111111100
001111111101
100111111101
110011111001
111111110011
111111100111
111110001111
I know this is not an ordinary boolean matrix, but it is useful for my example.
You can note there is sort of zero-paths in there...
I want to make a function that receives this matrix and a point where a zero is stored and that transforms every zero in the same area into a 2 (suppose the matrix can store any integer even it is initially boolean)
(just like when you paint a zone in Paint or any image editor)
suppose I call the function with this matrix M and the coordinate of the upper right corner zero, the result would be:
111011111112
110111111122
001111111121
100111111121
110011111221
111111112211
111111122111
111112221111
well, my question is how to do this iteratively...
hope I didn't mess it up too much
Thanks in advance!
Manuel
ps: I'd appreciate if you could show the function in C, S, python, or pseudo-code, please :D
There is a standard technique for converting particular types of recursive algorithms into iterative ones. It is called tail-recursion.
The recursive version of this code would look like (pseudo code - without bounds checking):
paint(cells, i, j) {
if(cells[i][j] == 0) {
cells[i][j] = 2;
paint(cells, i+1, j);
paint(cells, i-1, j);
paint(cells, i, j+1);
paint(cells, i, j-1);
}
}
This is not simple tail recursive (more than one recursive call) so you have to add some sort of stack structure to handle the intermediate memory. One version would look like this (pseudo code, java-esque, again, no bounds checking):
paint(cells, i, j) {
Stack todo = new Stack();
todo.push((i,j))
while(!todo.isEmpty()) {
(r, c) = todo.pop();
if(cells[r][c] == 0) {
cells[r][c] = 2;
todo.push((r+1, c));
todo.push((r-1, c));
todo.push((r, c+1));
todo.push((r, c-1));
}
}
}
Pseudo-code:
Input: Startpoint (x,y), Array[w][h], Fillcolor f
Array[x][y] = f
bool hasChanged = false;
repeat
for every Array[x][y] with value f:
check if the surrounding pixels are 0, if so:
Change them from 0 to f
hasChanged = true
until (not hasChanged)
For this I would use a Stack ou Queue object. This is my pseudo-code (python-like):
stack.push(p0)
while stack.size() > 0:
p = stack.pop()
matrix[p] = 2
for each point in Arround(p):
if matrix[point]==0:
stack.push(point)
The easiest way to convert a recursive function into an iterative function is to utilize the stack data structure to store the data instead of storing it on the call stack by calling recursively.
Pseudo code:
var s = new Stack();
s.Push( /*upper right point*/ );
while not s.Empty:
var p = s.Pop()
m[ p.x ][ p.y ] = 2
s.Push ( /*all surrounding 0 pixels*/ )
Not all recursive algorithms can be translated to an iterative algorithm. Normally only linear algorithms with a single branch can. This means that tree algorithm which have two or more branches and 2d algorithms with more paths are extremely hard to transfer into recursive without using a stack (which is basically cheating).
Example:
Recursive:
listsum: N* -> N
listsum(n) ==
if n=[] then 0
else hd n + listsum(tl n)
Iteration:
listsum: N* -> N
listsum(n) ==
res = 0;
forall i in n do
res = res + i
return res
Recursion:
treesum: Tree -> N
treesum(t) ==
if t=nil then 0
else let (left, node, right) = t in
treesum(left) + node + treesum(right)
Partial iteration (try):
treesum: Tree -> N
treesum(t) ==
res = 0
while t<>nil
let (left, node, right) = t in
res = res + node + treesum(right)
t = left
return res
As you see, there are two paths (left and right). It is possible to turn one of these paths into iteration, but to translate the other into iteration you need to preserve the state which can be done using a stack:
Iteration (with stack):
treesum: Tree -> N
treesum(t) ==
res = 0
stack.push(t)
while not stack.isempty()
t = stack.pop()
while t<>nil
let (left, node, right) = t in
stack.pop(right)
res = res + node + treesum(right)
t = left
return res
This works, but a recursive algorithm is much easier to understand.
If doing it iteratively is more important than performance, I would use the following algorithm:
Set the initial 2
Scan the matrix for finding a 0 near a 2
If such a 0 is found, change it to 2 and restart the scan in step 2.
This is easy to understand and needs no stack, but is very time consuming.
A simple way to do this iteratively is using a queue.
insert starting point into queue
get first element from queue
set to 2
put all neighbors that are still 0 into queue
if queue is not empty jump to 2.

Resources