Exam pseudocode recursive function - pseudocode

I have this exam question:
Look at this example of pseudocode:
algorithm A(a, b) {
// precond: a & b are type of Int
// postcond: what does this function return?
if (a == b)
return( 0 )
else if (a < b)
return (-A(b, a))
else
return (A(a-1, b-1));
}
The answers given are:
a) a-b
b) a+b
c) max(a,b)
d) Will loop infinitely
Personally I think it's d), but I just wanted to make sure.

The function terminates when a==b; so to show that it doesn't terminate, you could show that a & b never get closer together with successive calls -- which in this case, is pretty easy.
(The above does not take into account overflow. Also, (d) can't be correct, since it doesn't loop at all.)

As long as a and b are not equal,
If a is less than b, the next function call would make a>b.
(For example calling A(3,4) would return -A(4,3) )
Subsequently, the function calls would result in an infinite recursion, as it keeps returning A(a-1, b-1) without termination.
(For example calling A(4,3) would return A(3,2) which would return A(2,1) and so on)

The only value the function will return is 0. And that's when a == b. But then, 0 = a - b for all (a,b) so that a == b. So I think the right answer is a).

Related

Church numerals in lambda calculus

I need to find a function P such that (using Beta - reduction)
P(g, h, i) ->* (h, i, i+1).
I am allowed to use the successor function succ. From wikipedia I got
succ = λn.λf.λx.f(n f x)
My answer is P = λx.λy.λz.yz(λz.λf.λu.f(z f u))z
but I'm not quite sure about it. My logic was the λx would effectively get rid of the g term, then the λy.λz would bring in the h and i via the yz. Then the succ function would bring in i+1 last. I just don't know if my function actually replicates this.
Any help given is appreciated
#melpomene points out that this question is unanswerable without a specific implementation in mind (e.g. for tuples). I am going to presume that your tuple is implemented as:
T = λabcf.f a b c
Or, if you prefer the non-shorthand:
T = (λa.(λb.(λc.(λf.f a b c))))
That is, a function which closes over a, b, and c, and waits for a function f to pass those variables.
If that is the implementation in mind, and assuming normal Church numerals, then the function you spec:
P(g, h, i) ->* (h, i, i+1)
Needs to:
take in a triple (with a, b, and c already applied)
construct a new triple, with
the second value of the old triple
the third value of the old triple
the succ of the third value of the old triple
Here is such a function P:
P = λt.t (λghi.T h i (succ i))
Or again, if you prefer non-shorthand:
P = (λt.t(λg.(λh.(λi.T h i (succ i)))))
This can be partially cleaned up with some helper functions:
SND = λt.t (λabc.b)
TRD = λt.t (λabc.c)
In which case we can write P as:
P = λt.T (SND t) (TRD t) (succ (TRD t))

How to reverse a singly linked list recursively without modifying the pointers?

Recently I had an interview and the interviewer asked me to reverse a singly linked list without modifying the pointers(change the values only).
At the beginning I came up with a solution using a stack. He said that was OK and wanted me to do it recursively. Then I gave him a O(n^2) solution. But he said he needs a O(n) solution.
Anyone can help me?
Pseudocode
reverse (list):
reverse2 (list, list)
reverse2 (a, b):
if b != nil:
a = reverse2 (a, b.next)
if a != nil:
swap (a.data, b.data)
if a == b || a.next == b:
# we've reached the middle of the list, tell the caller to stop
return nil
else:
return a.next
else:
# the recursive step has returned nil, they don't want us to do anything
return nil
else:
# we've reached the end of the list, start working!
return a
One way I can think of doing it is recursing to the end accumulating the values in another list as you resurse to the end, then on the way out of the recursion writing the values back starting with the 1st value in the list. It would be O(2n). It's not much different from using a stack...
list = { a => b => c => d }
def recursive(acc, x)
if !x
return acc
end
acc.preprend(x)
return recursive(acc, x.next)
end
result = recursive([], list.first)
So first call is recursive([], a). result is now [a].
Second call is recursive([a], b). result turns into [b, a].
Third call is recursive([b, a], c). result is [c, b, a].
Fourth call is recursive([c, b, a], d), and result [d, c, b, a].
Fifth call gets caught by the if !x.
Tell your interviewer you need an additional structure, like someone else said above.

What does it mean to "close over" something?

I'm trying to understand closures, but literally every definition of a closure that I can find uses the same cryptic and vague phrase: "closes over".
What's a closure? "Oh, it's a function that closes over another function."
But nowhere can I find a definition of what "closes over" means. Can someone explain what it means for Thing A to "close over" Thing B?
A closure is a pair consisting of a code pointer and an environment pointer. The environment pointer contains all of the free variables of a given function. For example:
fun f(a, b) =
let fun g(c, d) = a + b + c + d
in g end
val g = f(1, 2)
val result = g(3, 4) (*should be 10*)
The function g contains two free variables: a and b. If you are not familiar with the term free variable, it is a variable that is not defined within the scope of a function. In this context, to close over something, means to remove any occurrences of a free variable from a function. The above example provides good motivation for closures. When the function f returns, we need to be able to remember what the values of a and b are for later. The way this is compiled, is to treat function g as a code pointer and a record containing all the free variables, such as:
fun g(c, d, env) = env.a + env.b + c + d
fun f(a, b, env) = (g, {a = a, b = b})
val (g, gEnv) = f(1, 2)
val result = g(3, 4, gEnv)
When we apply the function g, we supply the environment that was returned when calling function f. Note that now function g no longer has any occurrences of a variable that is not defined in its scope. We typically call a term that doesn't have any free variables as closed. If you are still unclear, Matt Might has an excellent in depth explanation of closure conversion at http://matt.might.net/articles/closure-conversion/
Same example in Javascript
Before closure conversion
function f(a, b){
function g(c, d) {
return a + b + c + d
}
return g
}
var g = f(1, 2)
var result = g(3, 4)
After closure conversion:
function g(c, d, env) {
return env.a + env.b + c + d
}
function f(a, b, env) {
return [g, {"a": a, "b": b}]
}
var [g, gEnv] = f(1, 2)
var result = g(3, 4, gEnv)
From apple documentation
Closures are self-contained blocks of functionality that can be passed
around and used in your code. Closures in Swift are similar to blocks
in C and Objective-C and to lambdas in other programming languages.
But what that means?
It means that a closure captures the variables and constants of the context in which it is defined, referred to as closing over those variables and constants.
I hope that helps!

Robust distance comparing predicate

I need a robust predicate defined by the following code:
CompareResult compareDistance(Point a, Point b, Point c, Point d) {
if (distance(a, b) > distance(c, d))
return Larger;
else if (distance(a, b) == distance(c, d))
return Equal;
else
return Smaller;
}
Due to the floating point arithmetic limitations we can't compute distance exactly (even its square), so if we just directly implement this code, the predicate will not be robust. I tried to find it in CGAL library, but couldn't.
Somewhat close to the predicate I need is compare_distance_to_point(Point p, Point q, Point r) predicate. It returns Smaller if distance(p, q) < distance(p, r), Equal if distance(p, q) == distance(p, r) and Larger otherwise. The first thought is to shift c and d by (c - a) vector, so we could call compare_distance_to_point(a, b, d + (c - a)), but this will violate robustness again. So, does anyone have an idea for adapting it?
If you take a kernel with exact predicates such as
Exact_predicates_inexact_constructions_kernel,
you can use the functor Compare_distance_3 which is a model of the concept CompareDistance_3.
Kernel::Compare_distance_3 cmp;
return cmp(a,b,c,d);

What's the formal term for a function that can be written in terms of `fold`?

I use the LINQ Aggregate operator quite often. Essentially, it lets you "accumulate" a function over a sequence by repeatedly applying the function on the last computed value of the function and the next element of the sequence.
For example:
int[] numbers = ...
int result = numbers.Aggregate(0, (result, next) => result + next * next);
will compute the sum of the squares of the elements of an array.
After some googling, I discovered that the general term for this in functional programming is "fold". This got me curious about functions that could be written as folds. In other words, the f in f = fold op.
I think that a function that can be computed with this operator only needs to satisfy (please correct me if I am wrong):
f(x1, x2, ..., xn) = f(f(x1, x2, ..., xn-1), xn)
This property seems common enough to deserve a special name. Is there one?
An Iterated binary operation may be what you are looking for.
You would also need to add some stopping conditions like
f(x) = something
f(x1,x2) = something2
They define a binary operation f and another function F in the link I provided to handle what happens when you get down to f(x1,x2).
To clarify the question: 'sum of squares' is a special function because it has the property that it can be expressed in terms of the fold functional plus a lambda, ie
sumSq = fold ((result, next) => result + next * next) 0
Which functions f have this property, where dom f = { A tuples }, ran f :: B?
Clearly, due to the mechanics of fold, the statement that f is foldable is the assertion that there exists an h :: A * B -> B such that for any n > 0, x1, ..., xn in A, f ((x1,...xn)) = h (xn, f ((x1,...,xn-1))).
The assertion that the h exists says almost the same thing as your condition that
f((x1, x2, ..., xn)) = f((f((x1, x2, ..., xn-1)), xn)) (*)
so you were very nearly correct; the difference is that you are requiring A=B which is a bit more restrictive than being a general fold-expressible function. More problematically though, fold in general also takes a starting value a, which is set to a = f nil. The main reason your formulation (*) is wrong is that it assumes that h is whatever f does on pair lists, but that is only true when h(x, a) = a. That is, in your example of sum of squares, the starting value you gave to Accumulate was 0, which is a does-nothing when you add it, but there are fold-expressible functions where the starting value does something, in which case we have a fold-expressible function which does not satisfy (*).
For example, take this fold-expressible function lengthPlusOne:
lengthPlusOne = fold ((result, next) => result + 1) 1
f (1) = 2, but f(f(), 1) = f(1, 1) = 3.
Finally, let's give an example of a functions on lists not expressible in terms of fold. Suppose we had a black box function and tested it on these inputs:
f (1) = 1
f (1, 1) = 1 (1)
f (2, 1) = 1
f (1, 2, 1) = 2 (2)
Such a function on tuples (=finite lists) obviously exists (we can just define it to have those outputs above and be zero on any other lists). Yet, it is not foldable because (1) implies h(1,1)=1, while (2) implies h(1,1)=2.
I don't know if there is other terminology than just saying 'a function expressible as a fold'. Perhaps a (left/right) context-free list function would be a good way of describing it?
In functional programming, fold is used to aggregate results on collections like list, array, sequence... Your formulation of fold is incorrect, which leads to confusion. A correct formulation could be:
fold f e [x1, x2, x3,..., xn] = f((...f(f(f(e, x1),x2),x3)...), xn)
The requirement for f is actually very loose. Lets say the type of elements is T and type of e is U. So function f indeed takes two arguments, the first one of type U and the second one of type T, and returns a value of type U (because this value will be supplied as the first argument of function f again). In short, we have an "accumulate" function with a signature f: U * T -> U. Due to this reason, I don't think there is a formal term for these kinds of function.
In your example, e = 0, T = int, U = int and your lambda function (result, next) => result + next * next has a signaturef: int * int -> int, which satisfies the condition of "foldable" functions.
In case you want to know, another variant of fold is foldBack, which accumulates results with the reverse order from xn to x1:
foldBack f [x1, x2,..., xn] e = f(x1,f(x2,...,f(n,e)...))
There are interesting cases with commutative functions, which satisfy f(x, y) = f(x, y), when fold and foldBack return the same result. About fold itself, it is a specific instance of catamorphism in category theory. You can read more about catamorphism here.

Resources