I'm currently learning about recursion, it's pretty hard to understand. I found a very common example for it:
function factorial(N)
local Value
if N == 0 then
Value = 1
else
Value = N * factorial(N - 1)
end
return Value
end
print(factorial(3))
N == 0 is the base case. But when i changed it into N == 1, the result is still remains the same. (it will print 6).
Is using the base case important? (will it break or something?)
What's the difference between using N == 0 (base case) and N == 1?
That's just a coincidence, since 1 * 1 = 1, so it ends up working either way.
But consider the edge-case where N = 0, if you check for N == 1, then you'd go into the else branch and calculate 0 * factorial(-1), which would lead to an endless loop.
The same would happen in both cases if you just called factorial(-1) directly, which is why you should either check for > 0 instead (effectively treating every negative value as 0 and returning 1, or add another if condition and raise an error when N is negative.
EDIT: As pointed out in another answer, your implementation is not tail-recursive, meaning it accumulates memory for every recursive functioncall until it finishes or runs out of memory.
You can make the function tail-recursive, which allows Lua to treat it pretty much like a normal loop that could run as long as it takes to calculate its result:
local function factorial(n, acc)
acc = acc or 1
if n <= 0 then
return acc
else
return factorial(n-1, acc*n)
end
return Value
end
print(factorial(3))
Note though, that in the case of factorial, it would take you way longer to run out of stack memory than to overflow Luas number data type at around 21!, so making it tail-recursive is really just a matter of training yourself to write better code.
As the above answer and comments have pointed out, it is essential to have a base-case in a recursive function; otherwise, one ends up with an infinite loop.
Also, in the case of your factorial function, it is probably more efficient to use a helper function to perform the recursion, so as to take advantage of Lua's tail-call optimizations. Since Lua conveniently allows for local functions, you can define a helper within the scope of your factorial function.
Note that this example is not meant to handle the factorials of negative numbers.
-- Requires: n is an integer greater than or equal to 0.
-- Effects : returns the factorial of n.
function fact(n)
-- Local function that will actually perform the recursion.
local function fact_helper(n, i)
-- This is the base case.
if (i == 1) then
return n
end
-- Take advantage of tail calls.
return fact_helper(n * i, i - 1)
end
-- Check for edge cases, such as fact(0) and fact(1).
if ((n == 0) or (n == 1)) then
return 1
end
return fact_helper(n, n - 1)
end
I am wondering whether its possible to implement in pure Prolog alone a binary decrementer which is bidirectional and deterministic. Example runs include and for mode (-,+):
?- dec(X,[0,0,1]).
X = [1,0,1]
?- dec(X,[1,1,1]).
X = [0,0,0,1]
And for mode (+,-):
?- dec([1,0,1],X).
X = [0,0,1]
?- dec([0,0,0,1],X).
X = [1,1,1]
Optionally none of the modes should leave any choice points. But mandatorily the implementation must be in pure Prolog alone, so no cut, no findall, no var, etc...
I already tried a definition as follows dec(X,Y) :- binary_plus([1],Y,X). using the binary adder here. But it doesn't pass the last test case, since I get dec([0,0,0,1],X). X = [1, 1, 1]; X = [1, 1, 1, 0] ; false..
The following two queries test for determinism. They do not succeed. Both run infinitely as is ; and fail with a given N. To indicate that non-termination is intended, the queries are prefixed with :/-&.
:/-& length(Bs,N), dec(Bs, Ds1), dif(Ds1, Ds2), dec(Bs, Ds2).
:/-& length(Ds,N), dec(Bs1, Ds), dif(Bs1, Bs2), dec(Bs2, Ds).
dec([1|Bs],[0|Bs]) :-
nil_or_ends_with_one(Bs).
dec([0|Bs],[1|Ds]) :-
deci(Bs, Ds).
nil_or_ends_with_one([]).
nil_or_ends_with_one([E|Es]) :-
ends_with_one(Es, E).
ends_with_one([], 1).
ends_with_one([E|Es], _) :-
ends_with_one(Es, E).
deci([1],[]).
deci([1|Bs],[0|Bs]) :-
Bs = [B|_],
ends_with_one(Bs, B).
deci([0|Bs],[1|Ds]) :-
deci(Bs, Ds).
The solution is still a bit too general, in that it accepts
?- dec([1,non_digit,1],[0,non_digit,1]).
This can be easily fixed but does not seem to be worth the cost.
I got a different solution which is not targeted towards a deep indexing Prolog, rather a flat indexing Prolog. So far all 4 test cases do not leave any choice point in Jekejeke Prolog which has full flat indexing. :-)
% check binary number
num([]).
num([X|Y]) :- dig(X, Y).
dig(1, []).
dig(T, [X|Y]) :- aux(T, X, Y).
aux(0, X, Y) :- dig(X, Y).
aux(1, X, Y) :- dig(X, Y).
% check binary number and its pseudo decrement
dec([X|Y], Z) :- dig(X, Y, Z).
dig(1, [], []).
dig(T, [X|Y], [U|V]) :- aux(T, U, V, X, Y).
aux(0, 1, Z, X, Y) :- dig(X, Y, Z).
aux(1, 0, [X|Y], X, Y) :- dig(X, Y).
https://gist.github.com/jburse/649f828c330ff3c770834ee8bca250a8#file-tarai-p
But the drawback of full flat indexing is the additional overhead when coding a predicate, to bring it into flat form. Flat form is also popular as the binary_plus/3 example shows. But the best would possibly be to have both flat and deep, and the later in a way that there exists a
deep dec/2 version which never leaves choice points.
Unlike Matlab, Octave Symbolic has no piecewise function. Is there a work around? I would like to do something like this:
syms x
y = piecewise(x0, 1)
Relatedly, how does one get pieces of a piecewise function? I ran the following:
>> int (exp(-a*x), x, 0, t)
And got the following correct answer displayed and stored in a variable:
t for a = 0
-a*t
1 e
- - ----- otherwise
a a
But now I would like to access the "otherwise" part of the answer so I can factor it. How do I do that?
(Yes, I can factor it in my head, but I am practicing for when more complicated expressions come along. I am also only really looking for an approach using symbolic expressions -- even though in any single case numerics may work fine, I want to understand the symbolic approach.)
Thanks!
Matlab's piecewise function seems to be fairly new (introduced in 2016b), but it basically just looks like a glorified ternary operator. Unfortunately I don't have 2016 to check if it performs any checks on the inputs or not, but in general you can recreate a 'ternary' operator in octave by indexing into a cell using logical indexing. E.g.
{#() return_A(), #() return_B(), #() return_default()}([test1, test2, true]){1}()
Explanation:
Step 1: You put all the values of interest in a cell array. Wrap them in function handles if you want to prevent them being evaluated at the time of parsing (e.g. if you wanted the output of the ternary operator to be to produce an error)
Step 2: Index this cell array using logical indexing, where at each index you perform a logical test
Step 3: If you need a 'default' case, use a 'true' test for the last element.
Step 4: From the cell (sub)array that results from above, select the first element and 'run' the resulting function handle. Selecting the first element has the effect that if more than one tests succeed, you only pick the first result; given the 'default' test will always succeed, this also makes sure that this is not picked unless it's the first and only test that succeeds (which it does so by default).
Here are the above steps implemented into a function (appropriate sanity checks omitted here for brevity), following the same syntax as matlab's piecewise:
function Out = piecewise (varargin)
Conditions = varargin(1:2:end); % Select all 'odd' inputs
Values = varargin(2:2:end); % Select all 'even' inputs
N = length (Conditions);
if length (Values) ~= N % 'default' case has been provided
Values{end+1} = Conditions{end}; % move default return-value to 'Values'
Conditions{end} = true; % replace final (ie. default) test with true
end
% Wrap return-values into function-handles
ValFuncs = cell (1, N);
for n = 1 : N; ValFuncs{n} = #() Values{n}; end
% Grab funhandle for first successful test and call it to return its value
Out = ValFuncs([Conditions{:}]){1}();
end
Example use:
>> syms x t;
>> F = #(a) piecewise(a == 0, t, (1/a)*exp(-a*t)/a);
>> F(0)
ans = (sym) t
>> F(3)
ans = (sym)
-3⋅t
ℯ
─────
9
I am studying for a final, and I have a practice problem here.
The question asks for the result of
val y = ref 1;
fun f x = (!y) + (x + x);
(f (y := (!y)+1; !y)) + (!y);
under the following parameter passing techniques:
Call by value
Call by name
Call by need.
It seems to me that for call by value, the answer is 8.
However, I believe the answer for call by name is also 8, but I would expect it to be different. The reason I think it is 8:
y := (!y)+1 derefs y as 1, adds 1, and then sets y to 2
!y in line 3 serves as the argument to f, and since it is being dereferenced it is
passed as a value rather than as a reference (this may be where I am
going wrong?)
The function call returns 6, but does not set y as y was passed in as a value from the previous step
6 is added to the dereferenced value of y, which is 2.
This returns 8
Is this the correct answer, and if not, can someone please point out where I have gone wrong? Also, can someone explain to me how call by need would work in this situation also?
Many thanks.
I found out how it works:
(y := (!y)+1; !y) is the parameter passed to f.
f then looks like:
fun f x = (!y) + ((y:= (!y)+1; !y) + (y:= (!y)+1; !y));
so this ends up being 1+2+3, and the final step + (!y) adds 3 as this is the current value of y, giving 9.
Thanks for pointing out that I was still doing call-by-value.
I have 16 unrelated binary strings (of the same length). eg. 100000001010, 010100010010 and so on, and I need to find out a bitstring in which position x is a 1 IF position x is 1 for ATLEAST 2 bitstrings out of the 16.
Initially, I tries using bitwise XOR and this works great as long as even number of strings contain a 1, but when odd number of strings contain 1, the answer given is reverse.
A simple example (with 3 strings) would be:
A: 10101010
B: 01010111
C: 11011011
f(A,B,C)= answer
Expected answer: 11011011
Answer I'm getting right now: 11011001
I know I'm wrong somewhere but I'm at a loss on how to proceed
Help much appreciated
You can do something like
unsigned once = x[0], twice = 0;
for (int i = 1; i < 16; ++i) {
twice |= once & x[i];
once |= x[i];
}
(A AND B) OR (A AND C) OR (B AND C)
This is higher complexity than what you had originally.