Forth, Hofstadter Q Sequence with Recursion - recursion

I'm attempting to implement Hofstadter's Q Sequence using the recursive definition:
Q(1) = 1
Q(2) = 1
Q(n) = Q(n - Q(n-2)) + Q(n - Q(n-1)) for n > 2
I get the wrong result for n > 3. Here's what I have so far:
: Q recursive
dup 3 <
if
drop 1
else
dup dup 2dup 2 - Q - Q -rot 1- Q - Q +
then ;
Try it online: http://ideone.com/PmnJRO (Edit: Now has the fixed, correct implementation)
I think it doesn't work because there are values added to the stack after each call of Q where n is greater than 2, making -rot not work as I expected.
Is there a simple adjustment to make this work? Or do I need to use a different approach, maybe using a variable for n?
OEIS: A005185

I realized my mistake. I didn't need to preserve n after calling Q, but I had used dup enough times to preserve it each call. This left n on the stack after each call, making the output incorrect. I removed one of the dup's and it works.

Related

Google Foobar Fuel Injection Perfection

Problem:
Fuel Injection Perfection
Commander Lambda has asked for your help to refine the automatic quantum antimatter fuel injection system for her LAMBCHOP doomsday device. It's a great chance for you to get a closer look at the LAMBCHOP - and maybe sneak in a bit of sabotage while you're at it - so you took the job gladly.
Quantum antimatter fuel comes in small pellets, which is convenient since the many moving parts of the LAMBCHOP each need to be fed fuel one pellet at a time. However, minions dump pellets in bulk into the fuel intake. You need to figure out the most efficient way to sort and shift the pellets down to a single pellet at a time.
The fuel control mechanisms have three operations:
Add one fuel pellet Remove one fuel pellet Divide the entire group of fuel pellets by 2 (due to the destructive energy released when a quantum antimatter pellet is cut in half, the safety controls will only allow this to happen if there is an even number of pellets) Write a function called solution(n) which takes a positive integer as a string and returns the minimum number of operations needed to transform the number of pellets to 1. The fuel intake control panel can only display a number up to 309 digits long, so there won't ever be more pellets than you can express in that many digits.
For example: solution(4) returns 2: 4 -> 2 -> 1 solution(15) returns 5: 15 -> 16 -> 8 -> 4 -> 2 -> 1
Test cases
Inputs: (string) n = "4" Output: (int) 2
Inputs: (string) n = "15" Output: (int) 5
my code:
def solution(n):
n = int(n)
if n == 2:
return 1
if n % 2 != 0:
return min(solution(n + 1), solution(n - 1)) + 1
else:
return solution(int(n / 2)) + 1
This is the solution that I came up with with passes 4 out of 10 of the test cases. It seems to be working fine so im wondering if it is because of the extensive runtime. I thought of applying memoization but im not sure how to do it(or if it is even possible). Any help would be greatly appreciated :)
There are several issues to consider:
First, you don't handle the n == "1" case properly (operations = 0).
Next, by default, Python has a limit of 1000 recursions. If we compute the log2 of a 309 digit number, we expect to make a minimum of 1025 divisions to reach 1. And if each of those returns an odd result, we'd need to triple that to 3075 recursive operations. So, we need to bump up Python's recursion limit.
Finally, for each of those divisions that does return an odd value, we'll be spawning two recursive division trees (+1 and -1). These trees will not only increase the number of recursions, but can also be highly redundant. Which is where memoization comes in:
import sys
from functools import lru_cache
sys.setrecursionlimit(3333) # estimated by trial and error
#lru_cache()
def solution(n):
n = int(n)
if n <= 2:
return n - 1
if n % 2 == 0:
return solution(n // 2) + 1
return min(solution(n + 1), solution(n - 1)) + 1
print(solution("4"))
print(solution("15"))
print(solution(str(10**309 - 1)))
OUTPUT
> time python3 test.py
2
5
1278
0.043u 0.010s 0:00.05 100.0% 0+0k 0+0io 0pf+0w
>
So, bottom line is handle "1", increase your recursion limit, and add memoization. Then you should be able to solve this problem easily.
There are more memory- and runtime-efficient ways to solve the problem, which is what Google is testing for with their constraints. Every time you recurse a function, you put another call on the stack, or 2 calls when you recurse twice on each function call. While they seem basic, a while loop was a lot faster for me.
Think of the number in binary - when ever you have a streak of 1s >1 in length at LSB side of the number, it makes sense to add 1 (which will flip that streak to all 0s but add another bit to the overall length), then shift right until you find another 1 in the LSB position. You can solve it in a fixed memory block in O(n) using just a while loop.
If you don't want or can't use functools, you can build your own cache this way :
cache = {}
def solution_rec(n):
n = int(n)
if n in cache:
return cache[n]
else:
if n <= 1:
return 0
if n == 2:
return 1
if n % 2 == 0:
div = n / 2
cache[div] = solution(div)
return cache[div] + 1
else:
plus = n + 1
minus = n - 1
cache[plus] = solution(n + 1)
cache[minus] = solution(n - 1)
return min(cache[plus], cache[minus]) + 1
However, even if it runs much faster and has less recursive calls, it's still too much recursive calls for Python default configuration if you test the 309 digits limit.
it works if you set sys.setrecursionlimit to 1562.
An implementation of #rreagan3's solution, with the exception that an input of 3 should lead to a subtraction rather than an addition even through 3 has a streak of 1's on the LSB side:
def solution(n):
n = int(n)
count = 0
while n > 1:
if n & 1 == 0:
n >>= 1
elif n & 2 and n != 3:
n += 1
else:
n -= 1 # can also be: n &= -2
count += 1
return count
Demo: https://replit.com/#blhsing/SlateblueVeneratedFactor

Implementing Schulze voting method in SciLab

I have to implement the Schulze method in SciLab. Unfortunately, I'm completely new to this tool and neither am I good at such kind of job. Could anyone advise something as to where to look for some examples and tools to do it as fast and easy as possible? The program shouldn't be extremely flexible or qualitative, it would be fine if it just worked with some hard-coded input. As I understand, the Schulze method can be implemented using graph and I've found a toolbox for SciLab. Should I use it?
Update:
Here's what I managed to come up with. The code is a total mess and I admit it since I'm really bad at working with such kind of languages. I've tested it with the example from Wikipedia, seems to work.
The code is too long so here's a pastebin
You can find a pseudo implementation on Wikipedia:
# Input: d[i,j], the number of voters who prefer candidate i to candidate j.
# Output: p[i,j], the strength of the strongest path from candidate i to candidate j.
for i from 1 to C
for j from 1 to C
if (i ≠ j) then
if (d[i,j] > d[j,i]) then
p[i,j] := d[i,j]
else
p[i,j] := 0
for i from 1 to C
for j from 1 to C
if (i ≠ j) then
for k from 1 to C
if (i ≠ k and j ≠ k) then
p[j,k] := max ( p[j,k], min ( p[j,i], p[i,k] ) )
Translating this to SciLab would require using functions, for-loops, if-else constructs, max, min.
Below I plainly translated the pseudo code into Scilab code. I haven't tested it and you'll have to find out the arguments to call it with.
function p = schulzeMethod(d, C)
// Initialize a zero matrix p of the same size as d
p = zeros(size(d))
for i = 1:C
for j = 1:C
if i ~= j then
if d(i,j) > d(j,i) then
p(i,j) = d(i,j)
else
p(i,j) = 0
end
end
end
end
for i = 1:C
for j = 1:C
if i ~= j then
for k = 1:C
if (i ~= k) & ( j ~= k) then
p(j,k) = max(p(j,k), min(p(j,i), p(i,k)))
end
end
end
end
end
endfunction
// Create some random values
C = 10
d = rand(C, C)
// Call the function above
p = schulzeMethod(d, C)
disp(p)
Good luck, hope it helps! Please give some feedback if it worked to help others.

Determining the big Oh for (n-1)+(n-1)

I have been trying to get my head around this perticular complexity computation but everything i read about this type of complexity says to me that it is of type big O(2^n) but if i add a counter to the code and check how many times it iterates per given n it seems to follow the curve of 4^n instead. Maybe i just misunderstood as i placed an count++; inside the scope.
Is this not of type big O(2^n)?
public int test(int n)
{
if (n == 0)
return 0;
else
return test(n-1) + test(n-1);
}
I would appreciate any hints or explanation on this! I completely new to this complexity calculation and this one has thrown me off the track.
//Regards
int test(int n)
{
printf("%d\n", n);
if (n == 0) {
return 0;
}
else {
return test(n - 1) + test(n - 1);
}
}
With a printout at the top of the function, running test(8) and counting the number of times each n is printed yields this output, which clearly shows 2n growth.
$ ./test | sort | uniq -c
256 0
128 1
64 2
32 3
16 4
8 5
4 6
2 7
1 8
(uniq -c counts the number of times each line occurs. 0 is printed 256 times, 1 128 times, etc.)
Perhaps you mean you got a result of O(2n+1), rather than O(4n)? If you add up all of these numbers you'll get 511, which for n=8 is 2n+1-1.
If that's what you meant, then that's fine. O(2n+1) = O(2⋅2n) = O(2n)
First off: the 'else' statement is obsolete since the if already returns if it evaluates to true.
On topic: every iteration forks 2 different iterations, which fork 2 iterations themselves, etc. etc. As such, for n=1 the function is called 2 times, plus the originating call. For n=2 it is called 4+1 times, then 8+1, then 16+1 etc. The complexity is therefore clearly 2^n, since the constant is cancelled out by the exponential.
I suspect your counter wasn't properly reset between calls.
Let x(n) be a number of total calls of test.
x(0) = 1
x(n) = 2 * x(n - 1) = 2 * 2 * x(n-2) = 2 * 2 * ... * 2
There is total of n twos - hence 2^n calls.
The complexity T(n) of this function can be easily shown to equal c + 2*T(n-1). The recurrence given by
T(0) = 0
T(n) = c + 2*T(n-1)
Has as its solution c*(2^n - 1), or something like that. It's O(2^n).
Now, if you take the input size of your function to be m = lg n, as might be acceptable in this scenario (the number of bits to represent n, the true input size) then this is, in fact, an O(m^4) algorithm... since O(n^2) = O(m^4).

Prolog - making a recursive divisor

Okay, so I'm a beginner in Prolog so I'm sorry if I can't quite get my question across very clearly but this is where I'm struggling:
divide_by(X, D, I, R) :- (D > X), I is 0, R is X.
divide_by(X, D, I, R) :-
X >= D,
X_1 is X - D,
I_1 is I + 1,
divide_by(X_1, D, I_1, R),
R is X_1.
I'm trying to write a program that will accept two arguments (X and D) and return the Iterations (I) and Remainder (R) so that it can display the result of X / D when the user enters:
divide_by(8,3,I,R). for example.
When tracing the code I know that I is incorrect because the first increment makes it equal to 0 and so the count for that is wrong. But I don't know how to declare I is 0 without it resetting every time it recurses through the loop. (I don't want to declare I as 0 in the query)
I also realised that when it has finished recursing (when X < D) then I is going to be set to 0 because of the base case.
Would anyone be kind enough to show me how I can fix this?
You need to introduce an accumulator and use a helper predicate, something like this:
divide(_,0,_,_) :- !, fail . % X/0 is undefined and so can't be solved.
divide(0,_,0,0) :- !. % 0/X is always 0.
divide(X,Y,Q,R) :- % the ordinary case, simply invoke the
divrem(X,Y,0,Q,R) % helper with the accumulator seeded with 0
.
divrem(X,Y,Q,Q,X) :- % if X < Y, we're done.
X < Y . %
divrem(X,Y,T,Q,R) :- % otherwise...
X >= Y , % as long as X >= Y,
X1 is X - Y , % compute the next X
T1 is T + 1 , % increment the accumulator
divrem(X1,Y,T1,Q,R) % recurse down
. % Easy!

SML currying question

I have a midterm coming up next week and I was just going over the sml notes provided in class. I came across a currying example and I was not sure exactly how it worked.
It is a simple function which computes the power of a number. Here is the function definition:
fun pow 0 n = 1 | pow k n = n*pow(k-1)n
I'm not sure how this function works when we pass it the following arguments:
val x = pow 2 2
This is the way I see it:
=2*pow(1)2
=2*(2*pow(0)2)2
=2*(2*(1)2)2)
The result we should be getting is four but I don't see how we get this result from the steps I have carried out above.
Help Please. Thank-You.
Ah, Standard ML of New Jersey, how I miss thee...
Anyway, let me go through this step by step. Remember that currying, unlike the dinner in front of me (which incidentally is a curry dish), is basically a way of dealing with only one argument at a time to return a new function. With that in mind, apply the first 2 to the given function. Since only one pattern matches, you now have a new function -- let's call it "curry":
curry n = n * pow 1 n
Note that you now have an "inner" version of the pow function to address. Doing so, again, one pattern matches. Let's call this inner curried function "rice":
rice n = n * pow 0 n
And one more, "shrimp" -- but this time, the other pattern matches:
shrimp n = 1
The recursion has terminated here, so you have:
rice n = n * 1
curry n = n * (n * 1)
Now, use the second 2 in your original pow 2 2 with the new curry function:
curry 2 = 2 * (2 * 1)
which of course is 4.
I highly doubt SML names the curried functions in this way, but I hope this does help to understand the concept. I take no responsibility if it also makes you hungry.
2*pow(1)2 =2*(2*pow(0)2)2
Here you expand pow 1 to 2 * pow 0 2 and leave the 2 after it be. This is wrong. pow 1 on its own would expand to (fn n => n * pow 0 2), only when applying it to the second argument as well it becomes 2 * pow 0 2. So the above should read:
2*pow(1)2 =2*(2*pow(0)2)
Now if we apply pow 0 2, we get 1 so the end result is:
2*pow(1)2 = 2*(2*pow(0)2) = 2*(2*1) = 4

Resources