views:

63

answers:

3

hi, im trying to solve this very first challange but i get stuck, i like fast program, so i decided to use recursive method not iteration

unfortunately, when the input is a big integer (100000 > input > 1000000), its often crash

so i debug it, and it shows stack overflow error

please help me, i dont know what to do, ive tried to change data type to unsigned long, unsigned int, etc, but none of it works

here is my code, im using ANSI C

#include "stdio.h"

int cek(int n) {
    return n % 2;
}

int fung(int n,int c) {
    if (n == 1) {
        return c;
    }
    if (!cek(n)) {
        return fung(n/2,++c);
    }
    else {
        return fung((n*3)+1,++c);
    }
}

int comp(int i,int j,int tmp) {
    int temp;
    if (i == j)
        return tmp;
    temp = fung(i,1);
    if (temp > tmp)
        return comp(++i,j,temp);
    else
        return comp(++i,j,tmp);
}

int main() {
    int i,j,tmp;
    while (scanf("%d %d",&i,&j)) {
        if (i > j) {
            tmp = i;
            i = j;
            j = tmp;
        }
        printf("%d %d %d\n",i,j,comp(i,j,0));
    }
    return 0;
}

PS: sorry for my stupidness, im really a newbie @_@

+2  A: 

Not a C expert, but usually there is a call stack depth limit enforced by the compiler. Probably you can change this with a compiler flag, but this will not solve your problem. Making the algortihm iterative instead of recursive will fix it.

Recursive algorithms won't go faster than iterative ones, usually. But they are typically nicer to understand. (= more elegant)

jvdneste
This problem is more elegantly expressed as a simple loop, rather than a recursive function, IMHO.
Thomas
+5  A: 

Recursion is not likely to be faster than iteration, and in fact it's likely to be slower.

The call stack has a limited size, and if your recursion goes deeper than that, there's nothing you can do about it. Especially in the Collatz problem, there's no way to tell up front how many steps you'll need. Rewrite this using an iterative method instead.

(If your compiler does tail call optimization, recursion might still work. But TCO is not required by the standard, so it will lead to unportable code. And apparently, your compiler does not optimize this particular tail call anyway.)

Thomas
Or he might not have optimizations enabled (for TCE). Actually, that is a scary thought!
leppie
Thank you for your information, but outhere i saw same recursive code, but in C++it works fine, not like minethats why im really frustated =_=here the codeunsigned int cycle(unsigned int curValue, unsigned int count){ if(curValue == 1) return count; if(isEven(curValue)) return cycle(curValue/2, count+1); else return cycle((curValue*3)+1, count+1);}
Ady
ahh, cant use code tag in comment lol @_@
Ady
@Ady Putra: And what about `comp`?
leppie
@leppi ive changed it with iterative method, so only the fung recursive method left, but still...
Ady
What he has isn't tail recursive.
Blindy
@Blindy: Interesting, I thought it was. The very last thing the function does is return the return value of a recursive call, unmodified. Why is this not tail recursive?
Thomas
Yea but there's 2 exit points separated by an `if`. Doesn't that violate the tail-recursive rules? The compiler seems to agree with me.
Blindy
@blindy: Both recursive calls to comp are in the tail position (or could be, with a sufficiently clever compiler, as there's nothing else to be done. However, replacing the whole if with "return comp(i+1, j (temp>tmp)?temp:tmp)", without a conditional around the call, might be easier for the compiler.
Vatine
you know what, my new code didnt pass UVa, time excedeed!!! =_=
Ady
@Vatine, that's what I would have written too to make the compiler accept it as tail recursive. As it is it seems it's too complex for it.
Blindy
A: 

Okay guys, i found it!!!

so this is my code, i still use recursion but only for the inner loop fung(),

im not really impressed of it, because its need 0,5 sec to count input 1 and 1000000, someone's code outhere can do it in 0 sec, LOL

i change the outer loop comp() with iterative method,

look here

#include "stdio.h"
/*#include "windows.h"*/

int cek(int n) {
    return n % 2;
}

unsigned int fung(unsigned int n,unsigned int c) {
    if (n == 1) return c;
    if (!cek(n)) return fung(n/2,++c);
    else return fung((n*3)+1,++c);
}

/*
Above recursion will looked like this in iterative method
int func(int n) {
    int c=1;
    while (n != 1) {
        c++;
        if (n % 2 == 0)
            n=n/2;
        else
            n=(n*3)+1;
    }
    return c;
}
*/

/*Outer Loop*/
int iter(int i,int j) {
    int tmp1=0,tmp2;
    while (i <= j) {
        tmp2 = fung(i,1);
        if (tmp1 < tmp2)
            tmp1 = tmp2;
        i++;
    }
    return tmp1;
}

int main() {
    unsigned int i,j,s,f;
    while (scanf("%d %d",&i,&j)) {            /*UVa Standard, infinite loop*/
        /*s = GetTickCount();*/
        printf("%d %d %d",i,j,iter(i,j));
        /*f = GetTickCount();
        printf("%lu\n",f-s);*/
    }
    return 0;
}
Ady
Please update your question, instead of answering it yourself.
Vatine