Recursive Merge Sort Without Arrays - recursion

This is a problem I'm working on right now without any idea how to solve. I'm supposed to write the pseudocode to the merge function, but I'm not sure what I'm supposed to do. What I've been given is as follows:
Begin MergeSort(L[], start, stop)
if (stop<=start) return;
int m = (start+stop)/2;
MergeSort(L, start, m);
Mergesort(L, m+1, stop);
merge(L, start, m, stop);
End MergeSort
The only other thing I've been told is that I'm supposed to find the "merge(L, start, m, stop);" line. I've been researching all day, and everything I've found says that you should have 2 arrays, called left and right, to assign the recursive lines, making:
Begin MergeSort(L[], start, stop)
if (stop<=start) return;
array left[];
array right[];
int m = (start+stop)/2;
left=MergeSort(L, start, m);
right=Mergesort(L, m+1, stop);
merge(L, start, m, stop);
End MergeSort
If I were given this problem, I would be able to solve it, but I'm stuck because once I've broken each sublist into single elements, I'm not even sure what I'm supposed to call them, so I'm not sure how to work with them.
I'm still a beginner when it comes to code (taking the very basics of C and Python), so please keep the answer simple, if possible.
Thank you very much for reading this, and I hope that I get an answer so I understand what I'm doing.

MergeSort consists of 2 functions: mergeSort and merge. First one you have already written correctly. So, the only you problem with merge function.
Because of merge sort is not in-space sort algorithm, it require extra space to store data. Bellow is pretty simplified version of merge function that creates extra array of size stop - start:
Begin merge(L[] array, int start, int m, int stop)
if (start == stop) {
return;
}
int leftPos = start;
int rightPos = m + 1;
int curPos = start;
L[] temp = new L[stop - start];
while(leftPos <= m && rightPos <= stop) {
if (array[leftPos] <= array[rightPos]) {
temp[curPos++] = array[leftPos++];
} else {
temp[curPos++] = array[rightPos++];
}
}
while(leftPos <= m) {
temp[curPos++] = array[leftPos++];
}
while(rightPos <= stop) {
temp[curPos++] = array[rightPos++];
}
for (int i = start; i <= stop; i++) {
array[i] = temp[i - start];
}
End merge

Related

Why is this recursive function exceeding call stack size?

I'm trying to write a function to find the lowest number that all integers between 1 and 20 divide. (Let's call this Condition D)
Here's my solution, which is somehow exceeding the call stack size limit.
function findSmallest(num){
var count = 2
while (count<21){
count++
if (num % count !== 0){
// exit the loop
return findSmallest(num++)
}
}
return num
}
console.log(findSmallest(20))
Somewhere my reasoning on this is faulty but here's how I see it (please correct me where I'm wrong):
Calling this function with a number N that doesn't meet Condition D will result in the function being called again with N + 1. Eventually, when it reaches a number M that should satisfy Condition D, the while loop runs all the way through and the number M is returned by the function and there are no more recursive calls.
But I get this error on running it:
function findSmallest(num){
^
RangeError: Maximum call stack size exceeded
I know errors like this are almost always due to recursive functions not reaching a base case. Is this the problem here, and if so, where's the problem?
I found two bugs.
in your while loop, the value of count is 3 to 21.
the value of num is changed in loop. num++ should be num + 1
However, even if these bugs are fixed, the error will not be solved.
The answer is 232792560.
This recursion depth is too large, so stack memory exhausted.
For example, this code causes same error.
function foo (num) {
if (num === 0) return
else foo(num - 1)
}
foo(232792560)
Coding without recursion can avoid errors.
Your problem is that you enter the recursion more than 200 million times (plus the bug spotted in the previous answer). The number you are looking for is the multiple of all prime numbers times their max occurrences in each number of the defined range. So here is your solution:
function findSmallestDivisible(n) {
if(n < 2 || n > 100) {
throw "Numbers between 2 and 100 please";
}
var arr = new Array(n), res = 2;
arr[0] = 1;
arr[1] = 2;
for(var i = 2; i < arr.length; i++) {
arr[i] = fix(i, arr);
res *= arr[i];
}
return res;
}
function fix(idx, arr) {
var res = idx + 1;
for(var i = 1; i < idx; i++) {
if((res % arr[i]) == 0) {
res /= arr[i];
}
}
return res;
}
https://jsfiddle.net/7ewkeamL/

Fibonacci series using alternate approach is not working

I have written a simple fibonacci series using recursion as below. But the below program is based on the formula fib(n)=fib(n-1)+fib(n-2).
Can we write a program to take a value of n and compute the fibonacci series using the formula fib(n+2)= fib(n)+fib(n+1). Can we write a program based on this formulae taking n as input.
public class FibonacciClass{
public static void main(String[] argv){
for (int index=0; index < 7; index++){
System.out.println("The Fibonacci series for the number "+index+" is " + fib(index));
}
}
private static int fib(int n){
if (n == 0 ) return 0;
if (n <= 2 ) return 1;
return (fib(n-1) + fib(n-2));
}
}
If we can solve the fib series using recursion, please let me know your inputs to write the program for the same.
hmm this sounds like you're trying to get an answer to a homework problem. But looks like you have legitimate reputation so:
Define
gib(n) = fib(n+2).
Use this to substitute for fib(n) and fib(n+1):
gib(n-2) = fib((n-2)+2) = fib(n)
gib(n-1) = fib((n-1)+2) = fib(n+1)
So the original equation becomes
fib(n+2)= fib(n)+fib(n+1) --> gib(n) = gib(n-2) + gib(n-1)
And we can recurse on this. We must make similar substitutions (n for n+2) in the code:
static unsigned int gib(int n)
{
if (n <= -2) return 0;
if (n == -1) return 1;
return gib(n - 2) + gib(n - 1);
}
I didnt include negative numbers that result in negative fibonacci (your code breaks on them too) so truly it needs to be returning "unsigned int". To modify for negative see here.

Dynamically increase size of list in Rcpp

I am trying to implement a "coupling to the past" algorithm in Rcpp. For this I need to store a matrix of random numbers, and if the algorithm did not converge create a new matrix of random numbers and store that as well. This might have to be done 10+ times or something until convergence.
I was hoping I could use a List and dynamically update it, similar as I would in R. I was actually very surprised it worked a bit but I got errors whenever the list size becomes large. This seems to make sense as I did not allocate the needed memory for the additional list elements, although I am not that familiar with C++ and not sure if that is the problem.
Here is an example of what I tried. however be aware that this will probably crash your R session:
library("Rcpp")
cppFunction(
includes = '
NumericMatrix RandMat(int nrow, int ncol)
{
int N = nrow * ncol;
NumericMatrix Res(nrow,ncol);
NumericVector Rands = runif(N);
for (int i = 0; i < N; i++)
{
Res[i] = Rands[i];
}
return(Res);
}',
code = '
void foo()
{
// This is the relevant part, I create a list then update it and print the results:
List x;
for (int i=0; i<10; i++)
{
x[i] = RandMat(100,10);
Rf_PrintValue(wrap(x[i]));
}
}
')
foo()
Does anyone know a way to do this without crashing R? I guess I could initiate the list at a fixed amount of elements here, but in my application the amount of elements is random.
You have to "allocate" enough space for your list. Maybe you can use something like a resizefunction:
List resize( const List& x, int n ){
int oldsize = x.size() ;
List y(n) ;
for( int i=0; i<oldsize; i++) y[i] = x[i] ;
return y ;
}
and whenever you want your list to be bigger than it is now, you can do:
x = resize( x, n ) ;
Your initial list is of size 0, so it expected that you get unpredictable behavior at the first iteration of your loop.

How to eliminate this type of recursion?

This is a bit more intricate than a simple left-recursion or tail-call recursion. So I'm wondering how I can eliminate this kind of recursion. I'm already keeping my own stack as you can see below, so the function needs to no params or return values. However, it's still calling itself up (or down) to a certain level and I want to turn this into a loop, but been scratching my head over this for some time now.
Here's the simplified test case, replacing all "real logic" with printf("dostuff at level #n") messages. This is in Go but the problem is applicable to most languages. Use of loops and goto's would be perfectly acceptable (but I played with this and it gets convoluted, out-of-hand and seemingly unworkable to begin with); however, additional helper functions should be avoided. I guess I should to turn this into some kind of simple state machine, but... which? ;)
As for the practicality, this is to run at about 20 million times per second (stack depth can range from 1 through 25 max later on). This is a case where maintaining my own stack is bound to be more stable / faster than the function call stack. (There are no other function calls in this function, only calculations.) Also, no garbage generated = no garbage collected.
So here goes:
func testRecursion () {
var root *TMyTreeNode = makeSomeDeepTreeStructure()
// rl: current recursion level
// ml: max recursion level
var rl, ml = 0, root.MaxDepth
// node: "the stack"
var node = make([]*TMyTreeNode, ml + 1)
// the recursive and the non-recursive / iterative test functions:
var walkNodeRec, walkNodeIt func ();
walkNodeIt = func () {
log.Panicf("YOUR ITERATIVE / NON-RECURSIVE IDEAS HERE")
}
walkNodeRec = func () {
log.Printf("ENTER LEVEL %v", rl)
if (node[rl].Level == ml) || (node[rl].ChildNodes == nil) {
log.Printf("EXIT LEVEL %v", rl)
return
}
log.Printf("PRE-STUFF LEVEL %v", rl)
for i := 0; i < 3; i++ {
switch i {
case 0:
log.Printf("PRECASE %v.%v", rl, i)
node[rl + 1] = node[rl].ChildNodes[rl + i]; rl++; walkNodeRec(); rl--
log.Printf("POSTCASE %v.%v", rl, i)
case 1:
log.Printf("PRECASE %v.%v", rl, i)
node[rl + 1] = node[rl].ChildNodes[rl + i]; rl++; walkNodeRec(); rl--
log.Printf("POSTCASE %v.%v", rl, i)
case 2:
log.Printf("PRECASE %v.%v", rl, i)
node[rl + 1] = node[rl].ChildNodes[rl + i]; rl++; walkNodeRec(); rl--
log.Printf("POSTCASE %v.%v", rl, i)
}
}
}
// test recursion for reference:
if true {
rl, node[0] = 0, root
log.Printf("\n\n=========>RECURSIVE ML=%v:", ml)
walkNodeRec()
}
// test non-recursion, output should be identical
if true {
rl, node[0] = 0, root
log.Printf("\n\n=========>ITERATIVE ML=%v:", ml)
walkNodeIt()
}
}
UPDATE -- after some discussion here, and further thinking:
I just made up the following pseudo-code which in theory should do what I need:
curLevel = 0
for {
cn = nextsibling(curLevel, coords)
lastnode[curlevel] = cn
if cn < 8 {
if isleaf {
process()
} else {
curLevel++
}
} else if curLevel == 0 {
break
} else {
curLevel--
}
}
Of course the tricky part will be filling out nextsibling() for my custom use-case. But just as a general solution to eliminating inner recursion while maintaining the depth-first traversal order I need, this rough outline should do so in some form or another.
I'm not really sure I understand what it is you want to do since your recursion code looks a little strange. However if I understand the structure of your TMyTreeNode then this is what I would do for a non recursive version.
// root is our root node
q := []*TMyTreeNode{root}
processed := make(map[*TMyTreeNode]bool
for {
l := len(q)
if l < 1 {
break // our queue is empty
}
curr := q[l - 1]
if !processed[curr] && len(curr.childNodes) > 0 {
// do something with curr
processed[curr] = true
q = append(q, curr.childNodes...)
continue // continue on down the tree.
} else {
// do something with curr
processed[curr] = true
q := q[:l-2] // pop current off the queue
}
}
NOTE: This will go arbitrarily deep into the structure. If that's not what you want it will need some modifications.

Handling large groups of numbers

Project Euler problem 14:
The following iterative sequence is
defined for the set of positive
integers:
n → n/2 (n is even) n → 3n + 1 (n is
odd)
Using the rule above and starting with
13, we generate the following
sequence: 13 → 40 → 20 → 10 → 5 → 16 →
8 → 4 → 2 → 1
It can be seen that this sequence
(starting at 13 and finishing at 1)
contains 10 terms. Although it has not
been proved yet (Collatz Problem), it
is thought that all starting numbers
finish at 1.
Which starting number, under one
million, produces the longest chain?
My first instinct is to create a function to calculate the chains, and run it with every number between 1 and 1 million. Obviously, that takes a long time. Way longer than solving this should take, according to Project Euler's "About" page. I've found several problems on Project Euler that involve large groups of numbers that a program running for hours didn't finish. Clearly, I'm doing something wrong.
How can I handle large groups of numbers quickly?
What am I missing here?
Have a read about memoization. The key insight is that if you've got a sequence starting A that has length 1001, and then you get a sequence B that produces an A, you don't to repeat all that work again.
This is the code in Mathematica, using memoization and recursion. Just four lines :)
f[x_] := f[x] = If[x == 1, 1, 1 + f[If[EvenQ[x], x/2, (3 x + 1)]]];
Block[{$RecursionLimit = 1000, a = 0, j},
Do[If[a < f[i], a = f[i]; j = i], {i, Reverse#Range#10^6}];
Print#a; Print[j];
]
Output .... chain length´525´ and the number is ... ohhhh ... font too small ! :)
BTW, here you can see a plot of the frequency for each chain length
Starting with 1,000,000, generate the chain. Keep track of each number that was generated in the chain, as you know for sure that their chain is smaller than the chain for the starting number. Once you reach 1, store the starting number along with its chain length. Take the next biggest number that has not being generated before, and repeat the process.
This will give you the list of numbers and chain length. Take the greatest chain length, and that's your answer.
I'll make some code to clarify.
public static long nextInChain(long n) {
if (n==1) return 1;
if (n%2==0) {
return n/2;
} else {
return (3 * n) + 1;
}
}
public static void main(String[] args) {
long iniTime=System.currentTimeMillis();
HashSet<Long> numbers=new HashSet<Long>();
HashMap<Long,Long> lenghts=new HashMap<Long, Long>();
long currentTry=1000000l;
int i=0;
do {
doTry(currentTry,numbers, lenghts);
currentTry=findNext(currentTry,numbers);
i++;
} while (currentTry!=0);
Set<Long> longs = lenghts.keySet();
long max=0;
long key=0;
for (Long aLong : longs) {
if (max < lenghts.get(aLong)) {
key = aLong;
max = lenghts.get(aLong);
}
}
System.out.println("number = " + key);
System.out.println("chain lenght = " + max);
System.out.println("Elapsed = " + ((System.currentTimeMillis()-iniTime)/1000));
}
private static long findNext(long currentTry, HashSet<Long> numbers) {
for(currentTry=currentTry-1;currentTry>=0;currentTry--) {
if (!numbers.contains(currentTry)) return currentTry;
}
return 0;
}
private static void doTry(Long tryNumber,HashSet<Long> numbers, HashMap<Long, Long> lenghts) {
long i=1;
long n=tryNumber;
do {
numbers.add(n);
n=nextInChain(n);
i++;
} while (n!=1);
lenghts.put(tryNumber,i);
}
Suppose you have a function CalcDistance(i) that calculates the "distance" to 1. For instance, CalcDistance(1) == 0 and CalcDistance(13) == 9. Here is a naive recursive implementation of this function (in C#):
public static int CalcDistance(long i)
{
if (i == 1)
return 0;
return (i % 2 == 0) ? CalcDistance(i / 2) + 1 : CalcDistance(3 * i + 1) + 1;
}
The problem is that this function has to calculate the distance of many numbers over and over again. You can make it a little bit smarter (and a lot faster) by giving it a memory. For instance, lets create a static array that can store the distance for the first million numbers:
static int[] list = new int[1000000];
We prefill each value in the list with -1 to indicate that the value for that position is not yet calculated. After this, we can optimize the CalcDistance() function:
public static int CalcDistance(long i)
{
if (i == 1)
return 0;
if (i >= 1000000)
return (i % 2 == 0) ? CalcDistance(i / 2) + 1 : CalcDistance(3 * i + 1) + 1;
if (list[i] == -1)
list[i] = (i % 2 == 0) ? CalcDistance(i / 2) + 1: CalcDistance(3 * i + 1) + 1;
return list[i];
}
If i >= 1000000, then we cannot use our list, so we must always calculate it. If i < 1000000, then we check if the value is in the list. If not, we calculate it first and store it in the list. Otherwise we just return the value from the list. With this code, it took about ~120ms to process all million numbers.
This is a very simple example of memoization. I use a simple list to store intermediate values in this example. You can use more advanced data structures like hashtables, vectors or graphs when appropriate.
Minimize how many levels deep your loops are, and use an efficient data structure such as IList or IDictionary, that can auto-resize itself when it needs to expand. If you use plain arrays they need to be copied to larger arrays as they expand - not nearly as efficient.
This variant doesn't use an HashMap but tries only to not repeat the first 1000000 numbers. I don't use an hashmap because the biggest number found is around 56 billions, and an hash map could crash.
I have already done some premature optimization. Instead of / I use >>, instead of % I use &. Instead of * I use some +.
void Main()
{
var elements = new bool[1000000];
int longestStart = -1;
int longestRun = -1;
long biggest = 0;
for (int i = elements.Length - 1; i >= 1; i--) {
if (elements[i]) {
continue;
}
elements[i] = true;
int currentStart = i;
int currentRun = 1;
long current = i;
while (current != 1) {
if (current > biggest) {
biggest = current;
}
if ((current & 1) == 0) {
current = current >> 1;
} else {
current = current + current + current + 1;
}
currentRun++;
if (current < elements.Length) {
elements[current] = true;
}
}
if (currentRun > longestRun) {
longestStart = i;
longestRun = currentRun;
}
}
Console.WriteLine("Longest Start: {0}, Run {1}", longestStart, longestRun);
Console.WriteLine("Biggest number: {0}", biggest);
}

Resources