Recursive functions in F# - recursion

I am not sure if this is the right place to ask this kind of question, so please don't hate.
I recently started learning F# for fun on edx.org. We had a lesson about recursion. The author of that course gave an interesting example:
let rec T a =
if a = 0 then
2
else
T (a - 1) * a
He then set a to be 4 and the result output was 48. I have been thinking about this one for some time now and I don't get it. Since 4 isn't equal to 0, we then get T (4 - 1) * 4, which is 12. Since a keeps decreasing by one every turn, which position takes the result 12? Is it T (3 - 1) * 12 or something else? How do we get the result 48?

T(4) = T(3)*4 = (T(2)*3)*4 = ((T(1)*2)*3)*4 = (((T(0)*1)*2)*3)*4) = 2*1*2*3*4 = 48

Related

What is non-trivial way of finding solution in systems of linear equations?

Hi!
I think I understood till (2.40) but i don't seem to understand
where the 0 = 8c1 + 2c2 - 1c3 + 0c4 came from.. where did this -1 and 0 is from?
In general these types of questions are probably better suited for https://math.stackexchange.com/ but since I like math and linear algebra I'll also answer your question.
The system of equations that you have has 4 variables and only 2 equations, so this means that you're going to have more than one solution and actually an infinite number of solutions. Not just anything will work though, so let's find what the solutions look like.
To simplify writing this let's call the 2x4 matrix A and the right hand side b=(42,8)T so what we are trying to solve is Ax = b. Also to write the zero vector (0,0)T I'll use ⍬ to save typing.
They first find a particular solution (some xp such that Axp = b) they do this with the first 2 columns and 0's for the other columns: xp = (42,8,0,0)T and when we plug this in we do get Axp = (42,8)T. Next they are trying to find the other solutions.
Notice that if we can find an x0 such that Ax0 = ⍬ then we can add this to our xp and it'll still be a solution: A(xp + x0) = Axp + Ax0 = b + ⍬ = b. So let's see if we can find an x0.
They do this in (2.40) by basically saying the 3rd and 4th column are not used in xp so let's see if we can make them 0 using the first two columns. Really we're looking for anything that'll give Ax0=⍬ and this is just an idea how we might find that.
Now notice that the 3rd column (8,2)T can be written as 8 times first column + 2 times second column. So if we do 8 first column + 2 second column - 1 times third column (+ zero times forth column) we get zero. This is just x0 = (8,2,-1,0)T because if we do Ax0 = A(8,2,-1,0)T = ⍬. Similarly we can find another one of these by using the forth column to get (-4,12,0,-1)T as another independent vector which I'll call x02 because I can't think of a better notation at the moment. Both of these satisfy Ax0 = ⍬, Ax02 = ⍬.
To make this really concrete you can see that computing A(xp+x0) = A(50,10,-1,0)T really does give you (42,8)T.
So we can add either or both to our original xp and it'll still be a solution that gives us the b we're looking for. A(xp + x0 + x02) = Axp + Ax0 + Ax02 = b + ⍬ + ⍬ = b Also any multiple of these x0 or x02 will work as well because for example A(3*x0) = 3*Ax0 = 3*⍬ = ⍬.
So really A(xp + c*x0 + d*x02) = Axp + c*Ax0 + d*Ax02 = b + c*⍬ + d*⍬ = b which means that any vector of the form xp + c*x0 + d*x02 where c and d are any numbers (scalars) will be a solution. This is our solution set and is what the last part (2.43) is saying.

Fibonacci sequence in solving an equation

Im trying to figure out an equation. This is f(n)=f(n-1) + 3n^2 - n. I also have the values to use as f(1), f(2), f(3). How would i go about solving this??
You would usually use recursion but, whether you do that or an iterative solution, you're missing (or simply haven't shown us) a vital bit of information, the terminating condition such as f(1) = 1 (for example).
With that extra piece of information, you could code up a recursive solution relatively easily, such as the following pseudo-code:
define f(n):
if n == 1:
return 1
return f(n-1) + (3 * n * n) - n
As an aside, that's not actually Fibonacci, which is the specific 1, 1, 2, 3, 5, 8, 13, ... sequence.
It can be said to be Fibonacci-like but it's actually more efficient to do this one recursively since it only involves one self-referential call per level whereas Fibonacci needs two:
define f(n):
if n <= 2:
return 1
return f(n-2) + f(n-1)
And if you're one of those paranoid types who doesn't like recursion (and I'll admit freely it can have its problems in the real world of limited stack depths), you could opt for the iterative version.
define f(n):
if n == 1:
return 1
parent = 1
for num = 2 to n inclusive:
result = parent + (3 * num * num) - num
parent = result
return result
If you ask this question on a programming site such as Stack Overflow, you can expect to get code as an answer.
On the other hand, if you are looking for a closed formula for f(n), then you should direct your question to a specialised StackExchange site such as Computer Science.
Note: what you are looking for is called the repertoire method. It can be used to solve your problem (the closed formula is very simple).

Recursion on staircase

I'm trying to understand the solution provided in a book to the following question:
"A child is running up a staircase with n steps and can hop either 1 step, 2 steps or 3 steps at a time. Implement a method to count how many possible ways the child can run up the stairs."
The book's solution is as follows, stemming from the fact that "the last move may be a single step hop from n - 1, a double step hop from step n - 2 or a triple step hop from step n - 3"
public static int countWaysDP(int n, int[] map) {
if (n < 0)
return 0;
else if (n == 0)
return 1;
else if (map[n] > -1)
return map[n];
else {
map[n] = countWaysDP(n - 1, map) + countWaysDP(n - 2, map) + countWaysDP(n - 3, map);
return map[n]; }
}
My confusion is:
Why should the program return 1 if the number of steps is zero? The way I think about it, if the number of steps is zero, then there are zero ways to traverse the staircase. Wouldn't a better solution be something like "if (n <= 0) return 0; else if (n == 1) return 1"?
I'm not sure I understand the rationale behind making this a static method? Google says that a static method is one that is called by the entire class, and not by an object of the class. So the book's intention seems to be something like:
.
class Staircase {
static int n;
public:
static int countWaysDP(int n, int[] map); }
instead of:
class Staircase {
int n;
public:
int countWaysDP(int n, int[] map); }
Why? What's the problem with there being multiple staircases instantiated by the class?
Thanks.
(Note: Book is Cracking the Coding Interview)
To answer your first question, it turns it is the beauty of mathematics: if there is 1 step for the staircase, there is 1 way to solve it. If there is 0 steps, there is also 1 way to solve it, which is to do nothing.
It is like, for an n-step staircase, for m times, you can either walk 1, 2, or 3 steps to finish it. So if n is 1, then m is 1, and there is 1 way. If n is 0, m is 0, and there is also 1 way -- the way of not taking any step at all.
If you write out all the ways for a 2-step staircase, it is [[1, 1], [2]], and for 1-step staircase, it is [[1]], and for 0-staircase, it is [[]], not []. The number of elements inside of the array [[]] is 1, not 0.
This will become the fibonacci series if the problem is that you can walk 1 step or 2 steps. Note that fib(0) = 1 and fib(1) = 1, and it corresponds to the same thing: when staircase is 1 step, there is 1 way to solve it. When there is 0 steps, there is 1 way to solve it, and it is by doing nothing. It turns out the number of ways to walk a 2-step staircase is fib(2) is 2 and it equals fib(1) + fib(0) = 1 + 1 = 2, and it wouldn't have worked if fib(0) were equal to 0.
Answer 2:
A Static method means the function doesn't need any information from the object.
The function just takes an input (in the parameters), processes it and returns something.
When you don't see any "this" in a function, you can set it as static.
Non-static methods usually read some properties (this-variables) and/or store values in some properties.
Answer 1:
I converted this to javascript, just to show what happens.
http://jsbin.com/linake/1/edit?html,js,output
I guess this is the point. Recursion often works opposite to what you could expect. It often returns values in the opposite order.
For 5 staircases:
First it returns n=1; then n=2, ... up to n=5;
n=5 has to wait until n=4 is ready, n=4 has to wait until n=3 is ready, ...
So here is your n=0 and n<0:
The first return of the function has n=1; that calls this
map[n] = countWaysDP(n - 1, map) + countWaysDP(n - 2, map) + countWaysDP(n - 3, map)
So that is
map[n] = countWaysDP(0, map) + countWaysDP(-1, map) + countWaysDP(-2, map)
There countWaysDP(0, map) returns 1; the other terms are meaningless, so they return 0. That's why there are these clauses for n==0 and n<0
notice, you can add
+ countWaysDP(n - 4, map)
if you want to see what happens when the child can also jump 4 cases
Also notice:
As I said in answer 2, you see this function doesn't require any object. It just processes data and returns something.
So, in your case, having this function in your class is useful because your functions are grouped (they 're not just loose functions scattered around your script), but making it static means the compiler doesn't have to carry around the memory of the object (especially the properties of the object).
I hope this makes sense. There are surely people that can give more accurate answers; I'm a bit out of my element answering this (I mostly do javascript).
To try and answer your first question, why it returns 1 instead of 0, say you're looking at a stair with 2 steps in total, the recursive call then becomes:
countWaysDP(2 - 1, map) + countWaysDP(2 - 2, map) + countWaysDP(2 - 3, map);
The second recursive call is the one where n becomes zero, that's when we have found a successful path, because from 2 steps, there's obviously a path of taking 2 steps. Now, if you write as you suggested:
n == 1: return 1
you would not accept taking two steps from the two stepped stair! What the statement means is that you only count the path if it ends with a single step!
You need to think about it has a tree with 3 possible options on each node.
If the size of the staircase is 4
we will have something like this:
(4)--1-->(3)--..(Choose a step and keep branching)...
|__2-->(2)--..(Until you get size of zero)............
|__3-->(1)--1-->(0) # <--Like this <--
At the end if you count all the leafs with size of zero you will get all the possible ways.
So you can think it like this, what if you take a step and then consider update the size of the stair like this size-step, where your steps can be (1,2,3)
Doing that you can code something like this:
choices = (1, 2, 3)
counter = 0
def test(size):
global counter
if size == 0:
counter += 1
for choice in choices:
if size - choice >= 0:
test(size - choice)
return counter

Number of Zero-crossings - Equation

I have written an algorithm that calculates the number of zero-crossings within a signal. By this, I mean the number of times a value changes from + to - and vice-versa.
The algorithm is explained like this:
If there are the following elements:
v1 = {90, -4, -3, 1, 3}
Then you multiply the value by the value next to it. (i * i+1)
Then taking the sign value sign(val) determine if this is positive or negative. Example:
e1 = {90 * -4} = -360 -> sigum(e1) = -1
e2 = {-4 * -3} = 12 -> signum(e2) = 1
e3 = {-3 * 1} = -3 -> signum(e3) = -1
e4 = {1 * 3} = 3 -> signum(e4) = 1
Therefore the total number of values changed from negative to positive is = 2 ..
Now I want to put this forumular, algorithm into an equation so that I can present it.
I have asked a simular question, but got really confused so went away and thought about it and came up with (what I think the equation should look like).. It's probably wrong, well, laughably wrong. But here it is:
Now the logic behind it:
I pass in a V (val)
I get the absolute value of the summation of the signum from calculating (Vi * Vi+1) .. The signum(Vi * Vi+1) should produce -1, 1, ..., values
If and only if the value is -1 (Because I'm only interested in the number of times zero is crossed, therefore, the zero values.
Does this look correct, if not, can anyone suggest improvements?
Thank you :)!
EDIT:
Is this correct now?
You are doing the right thing here but your equation is wrong simply because you only want to count the sign of the product of adjacent elements when it is negative. Dont sum the sign of products since positive sign products should be neglected. For this reason, an explicit mathematical formula is tricky as positive products between adjacent elements should be ignored. What you want is a function that takes 2 arguments and evaluates to 1 when their product is negative and zero when non-negative
f(x,y) = 1 if xy < 0
= 0 otherwise
then your number of crossing points is simply given by
sum(f(v1[i],v1[i+1])) for i = 0 to i = n-1
where n is the length of your vector/array v1 (using C style array access notation based on zero indexing). You also have to consider edge conditions such as 4 consecutive points {-1,0,0,1} - do you want to consider this as simply one zero crossing or 2??? Only you can answer this based on the specifics of your problem, but whatever your answer adjust your algorithm accordingly.

Looping vs recursion with F#

The example code here solves a project Euler problem:
Starting with the number 1 and moving to the right in a clockwise
direction a 5 by 5 spiral is formed as follows:
21 22 23 24 25
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
It can be verified that the sum of the numbers on the diagonals is
101.
What is the sum of the numbers on the diagonals in a 1001 by 1001
spiral formed in the same way?
but my question is a matter of functional programming style rather than about how to get the answer (I already have it). I am trying to teach myself a bit about functional programming by avoiding imperative loops in my solutions, and so came up with the following recursive function to solve problem 28:
let answer =
let dimensions = 1001
let max_number = dimensions * dimensions
let rec loop total increment increment_count current =
if current > max_number then total
else
let new_inc, new_inc_count =
if increment_count = 4 then increment + 2, 0
else increment, increment_count + 1
loop (total + current) new_inc new_inc_count (current + increment)
loop 0 2 1 1
However, it seems to me my function is a bit of a mess. The following imperative version is shorter and clearer, even after taking into account the fact that F# forces you to explicitly declare variables as mutable and doesn't include a += operator:
let answer =
let dimensions = 1001
let mutable total = 1
let mutable increment = 2
let mutable current = 1
for spiral_layer_index in {1..(dimensions- 1) / 2} do
for increment_index in {1..4} do
current <- current + increment
total <- total + current
increment <- increment + 2
total
Disregarding the fact that people with more maths ability have solved the problem analytically, is there a better way to do this in a functional style? I also tried using Seq.unfold to create a sequence of values and then piping the resulting sequence into Seq.sum, but this ended up being even messier than my recursive version.
Since you didn't describe the problem you're trying to solve, this answer is based only on the F# code you posted. I agree that the functional version is a bit messy, but I believe it could be clearer. I don't really understand the nested for loop in your imperative solution:
for increment_index in {1..4} do
current <- current + increment
total <- total + current
You're not using the increment_index for anything, so you could just multiply increment and current by four and get the same result:
total <- total + 4*current + 10*increment
current <- current + 4*increment
Then your imperative solution becomes:
let mutable total = 0
let mutable increment = 2
let mutable current = 1
for spiral_layer_index in {1..(dimensions- 1) / 2} do
total <- total + 4*current + 10*increment
current <- current + 4*increment
increment <- increment + 2
total
If you rewrite this to a recursive function, it becomes just:
let rec loop index (total, current, increment) =
if index > (dimensions - 1) / 2 then total
else loop (index + 1) ( total + 4*current + 10*increment,
current + 4*increment, increment + 2 )
let total = loop 1 (0, 2, 1)
The same thing could be also written using Seq.fold like this (this is even more "functional", because in functional programming, you use recursion only to implement basic functions, like fold that can then be re-used):
let total, _, _=
{1 .. (dimensions - 1) / 2} |> Seq.fold (fun (total, current, increment) _ ->
(total + 4*current + 10*increment, current + 4 * increment, increment + 2)) (0, 1, 2)
NOTE: I'm not sure if this actually implements what you want. It is just a simplification of your imperative solution and then rewrite of that using a recursive function...
In fact, this is Project Euler Problem 28 and my F# solution circa November 21, 2011 is quite similar to one suggested in Tomas' answer:
let problem028 () =
[1..500]
|> List.fold (fun (accum, last) n ->
(accum + 4*last + 20*n, last + 8*n)) (1,1)
|> fst
Indeed, solution of the original problem takes just one-liner simple fold over the list of all involved squares with corners at diagonal nodes while threading through the accumulated sum and value of current diagonal element. Folding is one of the major idioms of functional programming; there is a great classic paper A tutorial on the universality and expressiveness of fold that covers many important facets of this core pattern.

Resources