Problems with understanding recursion - recursion

I have problems with understanding recursion, I don't get the explanations in books and tutorials. The example below finds the greatest value in a list, here I get stuck at the second line, I simply don't understand what is happening after max([H|T], Max) when H > Max ->
I would really appreciate if I could get an explanation of all the steps in the code, for instance why it goes -> max(T, H); and -> Max.
max([H|T]) -> max(T, H).
max([H|T], Max) when H > Max -> max(T, H);
max([_|T], Max) -> max(T, Max);
max([], Max) -> Max.
Many thanks!
E.

I tried to explain step by step. Let's assume that you have a list: [2, 3, 1]
max([2, 3, 1]).
H=2 , T=[3, 1]
max([H|T]) -> max(T, H).
H=3, T=[1], Max=2
max([H|T], Max) when H > Max -> max(T, H);
Here when block says: if H is greater than Max then call max function again as max([1], 3).
Here we are again but with different values:
H=1, T=[], Max=3
max([H|T], Max) when H > Max -> max(T, H);
1 > 3 is false so when block fails and trying next max function definition which leads to step 5.
We know H is less than Max because step 4 failed so we are ignoring it.
T = [], Max=3
max([_|T], Max) -> max(T, Max);
We are matching last function definition which says max element found:
[] = [], Max = 3
max([], Max) -> Max.

Best way to understand recursion is by visualizing it. Let me give you a very simple example:
Suppose you want to know what is eligibility to become a prime minister of US, which is:
You have to be national citizen of US, for which here is the rule:
You are a natural born of US (or)
Your parents are national citizen of US
Now, first option straight forward makes you citizen of US, or same whole thing applies to your parents, which may again check for their parents ..and so on.
So there will be a straight forward answer, which is here 1st option. That is called Base Case. And in 2nd option you might apply same process of checking citizenship for your parents.
Here is a very simple pseudo code that can explain recursion:
isEligibleForPrimeMinister checkCitizenship(You, yourParents){
Base Case {returns true(That you are US citizen)}
checkCitizenship(yourParents, YourGrandParents)
}
Hope this helps.

This function could be rewritten like this:
max([H|T]) -> max(T, H).
max([], Max) -> Max;
max([H|T], Max) ->
NewMax = if H > Max -> H;
true -> Max
end,
%% NewMax = erlang:max(H, Max),
max(T, NewMax).
To understand it you must know how pattern matching works.
We take the head element of the list and consider it current maximum. We need to look at all the rest elements that are in the tail and check if any of them is greater.
If the rest of the list is empty, the current maximum is the result.
If the list is not empty take new head and determine the new maximum. Then go on with the rest of the list and new maximum. The thing that must be noticed here is that list passed to the next iteration of max/2 is always the tail of the previously passed value so we don't check values we already saw.

The last three lines in your code are all different clauses of the same function (max/2). This means that whenever the max function is called with two arguments passed, it will be pattern-matched against these three clauses.
This clause:
max([_|T], Max) -> max(T, Max);
will match whenever the list is non-empty and the head of the list (H) is less than or equal to Max. It will call max/2 passing T which is a list and Max which is a number. This new call will also be pattern-matched against the three clauses.
This clause:
max([], Max) -> Max.
will match whenever the list is empty and will return just Max which is a number.

Related

Smallest distance in a list to the number 0 supplies amount of that number with map

I want to create a function absmin which gets a list of floating point numbers and returns the amount of that number which has the smallest distance to 0.
We should do it with the function map. My first idea was that the function abs mentioned the problem with amount, but know my question is, how it is possible to create the point with the smallest distance to 0 and that with the map function, can somebody help me?
absmin :: [Double] -> Int
absmin [] = []
absmin (x:xs) = abs (map (x:xs))
Okay, now i changed to:
absmin xs = map abs xs
But with the specification: absmin :: [Double] -> Double it didn't work, maybe i´m to stupid, but i try and try and it didn't work
If you have a list like [3.14, 2.98, -0.1] and need to find which number is closest to zero, you need to first map abs to that list, and then you need to find the min.
Now min has signature Ord a => a -> a -> a so it only considers two numbers at the same time. Fortunately we can use a fold to fold this function over our list.
Prelude> absmin = foldr1 min . map abs
Prelude> absmin [3.14, 2.98, -0.1]
0.1
The problem with this is that we don't know if the closest number to zero was 0.1 or -0.1.
So let's map each element to a tuple containing its absolute value and the original value. We can define a minBy function that lets us find the minimum of two values based on a function like fst.
After we've folded this function over the list of tuples, we just need to call snd on the result to get the original value.
Prelude> :{
Prelude| minBy f a b
Prelude| | f a <= f b = a
Prelude| | otherwise = b
Prelude| :}
Prelude> absmin' = snd . foldr1 (minBy fst) . map (\x -> (abs x, x))
Prelude> absmin' [3.14, 2.98, -0.1, 0.1]
-0.1
You can use the min() and abs() functions to find the smallest absolute value in a list of numbers, and then use map() to apply this value to each element in the list.

How do I check if the path from a node to another has a depth equal to a given one in a graph in OCaml?

First of all, I'm sorry for how I wrote my question.
Anyway, I'm trying to write a function in OCaml that, given a graph, a max depth, a starting node, and another node, returns the list of the nodes that make the path but only if the depth of it is equal to the given one. However, I can't implement the depth part.
This is what I did:
let m = [(1, 2, "A"); (2, 3, "A");
(3, 1, "A"); (2, 4, "B");
(4, 5, "B"); (4, 6, "C");
(6, 3, "C"); (5, 7, "D");
(6, 7, "D")]
let rec vicini n = function
[] -> []
| (x, y, _)::rest ->
if x = n then y :: vicini n rest
else if y = n then x :: vicini n rest
else vicini n rest
exception NotFound
let raggiungi m maxc start goal =
let rec from_node visited n =
if List.mem n visited then raise NotFound
else if n = goal then [n]
else n :: from_list (n :: visited) (vicini n m)
and from_list visited = function
[] -> raise NotFound
| n::rest ->
try from_node visited n
with NotFound -> from_list visited rest
in start :: from_list [] (vicini start m)
I know I have to add another parameter that increases with every recursion and then check if its the same as the given one, but I don't know where
I am not going to solve your homework, but I will try to teach you how to use recursion.
In programming, especially functional programming, we use recursion to express iteration. In an iterative procedure, there are things that change with each step and things that remain the same on each step. An iteration is well-founded if it has an end, i.e., at some point in time, the thing that changes reaches its foundation and stops. The thing that changes on each step, is usually called an induction variable as the tribute to the mathematical induction. In mathematical induction, we take a complex construct and deconstruct it step by step. For example, consider how we induct over a list to understand its length,
let rec length xs = match xs with
| [] -> 0
| _ :: xs -> 1 + length xs
Since the list is defined inductively, i.e., a list is either an empty list [] or a pair of an element x and a list, x :: list called a cons. So to discover how many elements in the list we follow its recursive definition, and deconstruct it step by step until we reach the foundation, which is, in our case, the empty list.
In the example above, our inductive variable was the list and we didn't introduce any variable that will represent the length itself. We used the program stack to store the length of the list, which resulted in an algorithm that consumes memory equivalent to the size of the list to compute its length. Doesn't sound very efficient, so we can try to devise another version that will use a variable passed to the function, which will track the length of the list, let's call it cnt,
let rec length cnt xs = match xs with
| [] -> cnt
| _ :: xs -> length (cnt+1) xs
Notice, how on each step we deconstruct the list and increment the cnt variable. Here, call to the length (cnt+1) xs is the same as you would see in an English-language explanation of an algorithm that will state something like, increment cnt by one, set xs to the tail xs and goto step 1. The only difference with the imperative implementation is that we use arguments of a function and change them on each call, instead of changing them in place.
As the final example, let's devise a function that checks that there's a letter in the first n letters in the word, which is represented as a list of characters. In this function, we have two parameters, both are inductive (note that a natural number is also an inductive type that is defined much like a list, i.e., a number is zero or the successor of a number). Our recursion is also well-founded, in fact, it even has two foundations, the 0 length and the empty list, whatever comes first. It also has a parameter that doesn't change.
let rec has_letter_in_prefix letter length input =
length > 0 && match input with
| [] -> false
| char :: input ->
char = letter || has_letter_in_prefix letter (length-1) input
I hope that this will help you in understanding how to encode iterations with recursion.

Return values in Prolog

I'm supposed to write a predicate that does some math stuff. But I don't know how to pass numbers or return numbers.
Maybe you can give me an example?
Let's say a predicate divide/2 that takes two numbers a and b and returns a/b.
Yes, you pass numbers in in some arguments, and you get the result back in some other argument(s) (usually last). For example
divide( N, D, R) :-
R is N / D.
Trying:
112 ?- divide(100,5,X).
X = 20.
113 ?- divide(100,7,X).
X = 14.285714285714286.
Now, this predicate is divide/3, because it has three arguments: two for inputs and one for the output "information flow".
This is a simplified, restricted version of what a Prolog predicate can do. Which is, to not be that uni-directional.
I guess "return" is a vague term. Expression languages have expressions e-value-ated so a function's last expression's value becomes that function's "return" value; Prolog does not do that. But command-oriented languages return values by putting them into some special register. That's not much different conceptually from Prolog putting some value into some logvar.
Of course unification is more complex, and more versatile. But still, functions are relations too. Predicates "return" values by successfully unifying their arguments with them, or fail to do so, as shown in the other answer.
Prolog is all about unifying variables. Predicates don't return values, they just succeed or fail.
Typically when a predicate is expected to produce values based on some of the arguments then the left-most arguments are inputs and the right-most are the outputs. However, many predicates work with allowing any argument to be an input and any to be a output.
Here's an example for multiply showing how it is used to perform divide.
multiply(X,Y,Z) :- number(X),number(Y),Z is X * Y.
multiply(X,Y,Z) :- number(X),number(Z),X \= 0,Y is Z / X.
multiply(X,Y,Z) :- number(Y),number(Z),Y \= 0,X is Z / Y.
Now I can query it like this:
?- multiply(5,9,X).
X = 45 .
But I can easily do divide:
?- multiply(5,X,9).
X = 1.8 .
It even fails if I try to do a division by 0:
?- multiply(X,0,9).
false.
Here's another approach. So let's say you have a list [22,24,34,66] and you want to divide each answer by the number 2. First we have the base predicate where if the list is empty and the number is zero so cut. Cut means to come out of the program or just stop don't go to the further predicates. The next predicate checks each Head of the list and divides it by the number A, meaning (2). And then we simply print the Answer. In order for it to go through each element of the list we send back the Tail [24,34,66] to redo the steps. So for the next step 24 becomes the Head and the remaining digits [34,66] become the Tail.
divideList([],0,0):-!.
divideList([H|T],A,Answer):-
Answer is H//A,
writeln(Answer),
divideList(T,A,_).
?- divideList([22,24,34,66],2,L).
OUTPUT:
11
12
17
33
Another simpler approach:
divideList([],_,[]).
divideList([H|T],A,[H1|L]):-
H1 is H//A,!,
divideList(T,A,L).
?-divideList([22,4,56,38],2,Answer).
Answer = [11, 2, 28, 19]

Can someone help me with this formula ? (Standard deviation)

So I just started to learn Java, but my prof. just gave us this wild formula which we have to translate into code. I can't figure it out how to make this possible, can someone help me ?
σ means Standard deviation
µ means average
x means The Array x
N means N variables
]
The Σ upper-case Sigma character simply means the sum of.
So, for every data value, subtract the mean (average, in layman's terms) and square the result. Add all of those values together, divide it by the number of data values minus one, then take the square root of that.
Psuedo-code for that would be something like below. First, a function for calculating mean:
def calcMean(collection):
# Initialise for working out mean (sum / count).
sum = 0, count = 0
# Add every item to the sum and keep count.
for item in collection:
sum = sum + item
count = count + 1
# Avoid dive by zero, you choose what to do.
if count == 0:
handle empty collection somehow
# Return the mean.
return sum / count
Then using that to calculate the standard deviation:
def calcStdDev(collection):
# Get mean of the collection, initialise accumulator and count.
mean = calcMean(collection)
accum = 0, count = 0
for item in collection:
# Accumulate each '(item-mean) squared' value.
diff = item - mean
accum = accum + diff * diff
# Avoid dive by zero, you choose what to do.
if count < 2:
handle too-small collection somehow
# Divide and square root for result.
return sqrt(sum / (count - 1))
Now your job is to turn that pseudo-code into Java, something that should be a bit easier than turning the formula into Java.

prolog recursive error (easy)

I'm new to prolog. I'm doing a recursive program the problem is that even though it prints the answer.. it doesn't stop after printing the answer and eventually gives "Out of local stack".
I've read it could be a left recursion issue but as I've already told you I'm new to prolog and I don't really understand what happens...
so.. here's code.
f(X, Y):-
Y is sqrt(1-((X-1)*(X-1))).
sum(SEGMENTS, 1, TOTAL):-
f(2/SEGMENTS*1,H1),
TOTAL is (2/SEGMENTS)*H1.
sum(SEGMENTS, NR, TOTAL):-
N1 is (NR-1),
sum(SEGMENTS, N1, S1),
f(2/SEGMENTS*NR,H1),
f(2/SEGMENTS*N1,H2),
TOTAL is S1 + (2/SEGMENTS)*((H1+H2)/2).
It's supposed to calculate a semicircle area with the trapezoid rule or something similar.
As I've already told you .. it does finishes but after getting to the base case sum(segments, 1, total) it calls the function with the second alternative... :S
Thanks guys!
Also: Here's what I get when I run it
?- sum(3000,3000,TOTAL).
TOTAL = 1.5707983753431007 ;
ERROR: Out of local stack
The problem is that backtracking will attempt the case of NR value of 1 on the second sum clause after the first clause has succeeded. This causes a long recursion process (since NR is being decremented continually for each recursive call, attempting to wrap around through all negative integer values, etc).
A simple way to resolve the problem is in your second sum clause. Since the intention is that it is for the case of NR > 1, put NR > 1 as your first statement:
sum(SEGMENTS, NR, TOTAL) :-
NR > 1,
N1 is (NR-1),
sum(SEGMENTS, N1, S1),
f(2/SEGMENTS*NR,H1),
f(2/SEGMENTS*N1,H2),
TOTAL is S1 + (2/SEGMENTS)*((H1+H2)/2).
Also note that the expression f(2/SEGMENTS*NR, H1) doesn't compute the expression 2/SEGMENTS*NR and pass it to f. It actually passes that expression symbolically. It just happens to work here because f includes it on the right hand side of an is/2 so it is evaluated as desired. If you trace it, you'll see what I mean.

Resources