recursive function error: "stack overflow" - c++

I wrote this function that supposed to find smallest positive integer that is divisible by every number 1 through 20. I get "stack overflow error", even though, when I test for numbers 1 through 10, it works just fine.
here is my code:
#include<iostream>
#include<cstdlib>
using namespace std;
// function prototype
int smallPos(int k, int m,int n);
int main(){
printf("the smallest positive number that is divisible by 1 through 20 is %d ", smallPos(1,1,13));
}
int smallPos(int k, int n, int m){
int div=0;
for(int i = n;i<=m;i++) {
if (k%i==0)
div++;
}
if (div==m) {
return k;
} else {
k+=1;
smallPos(k,n,m);
}
}
Why does it happen? The number shouldn't be that big anyway.
Thank you!

The final condition (div == m) will never be true. For div to become equal to m, the number k should be divisible by all of the numbers in range [n,m).
Edit: I've reread the text in the printf() call to understand what the function does. You're looking for the first number divisible by all numbers in the range. If my calculations are correct, this number should be the product of all unique prime factors of the numbers in the range. For the range [1,13] (as per the function call, not the text), this number should be:
30030 = 1 * 2 * 3 * 5 * 7 * 9 * 11 * 13
Now, this means you are going to invoke the function recursively over 30,000 times, which is obviously way too many times for the size of stack you're using (defaults are relatively small). For a range this size, you should really consider writing an iterative function instead.
Edit: here's an iterative version that seems to work.
int smallPos ( int n, int m )
{
int k = 0;
while ( ++k )
{
int count = 0;
for (int i = n; i<=m; i++)
{
if (k%i==0) {
++count;
}
}
if (count == (m-n+1)) {
return k;
}
}
return k;
}
Indeed, the result for smallPos(1,10), the result is 2520. It seems my previous estimate was a lower bound, not a fixed result.

Your smallPos function incurs undefined behaviour since it is not returning a value in all execution paths. You may want to say return smallPos(k,n,m); in the last part (or just return smallPos(k + 1, n, m); in one go).

Related

How to check each element in an array if its prime or not

I'm trying to make program that prints out values form an array and that if they are or are not prime numbers. So far I have been able to make program which can take one value and print out if it's prime or not, however I haven't been able to implement this over to arrays. Here are my codes for printing out single numbers.
int isElementPrime(int value) {
if (0 == value % 2 || value < 2)
{
printf_s("Number %d is not prime\n", value);
}
else
{
printf_s("Number %d is prime\n", value);
}
return 0;
int main() {
int value = 4;
isElementPrime(value);
Output:
Number 4 is not prime
So the question is, how can this same thing be implemented to work with arrays?
EDIT As someone referred below, code is intended to only work up to number 8.
you want something as this?
int isElementPrime(int value) {
if (0 == value % 2 || value < 2)
{
printf_s("Number %d is not prime\n", value);
}
else
{
printf_s("Number %d is prime\n", value);
}
return 0;
}
int main() {
int values[4] = {1,2,3,4};
for(int i = 0; i < values.size();i++)
isElementPrime(values[i]);
a simple although inefficient way way to check if a number is prime is to loop through all of the whole integers from 2 up until the square root of the number in question and check if the loop counter (which will be between 2 and value exclusive) divides evenly into the tested value (with no remainder). This is a good place to start, you can then think about how to avoid unnecessary loop iterations.

Memory + dynamic programming or recursion

Problem is that i have 64 megabytes on solution,so i can use only 16,777,216 int numbers.
But for answer i must use 33,333,333 numbers,so some answers will not be considered.
Actually, problem is this.
By the way, i had my own code instead:
#include <iostream>
using namespace std;
int sq(int x) {
return (long long)(x*x) %(1000000);
}
int func(int x) {
if (x==0)
return 3;
else {
return ( sq(func(x-1))+2)%(1000000);
}
}
int main()
{
/*const int num=16 777 216;
int* arr=new int [num];
arr[0]=3;
for (int i=1;i<num;i++)
arr[i]=((arr[i-1]%(1000000))*(arr[i-1])%(1000000)+2)%(1000000);*/
int t,rez;
int n;
cin>>t;
for (int p=0;p<t;p++) {
cin>>n;
if (n%3!=0) {
rez=0;
} else {
// rez=arr[n/3-1];
rez=func(n/3-1);
}
cout<<rez<<endl;
}
return 0;
}
In comments there is second solution.
I can do it with recursion, but i have limit in 1 second.
So what code would be OK?
You do not need anywhere near that many entries (10^9 / 3). Note that you need only the values mod 10^6. You have a recurrence relationship among these:
a[n] = a[n-1]^2 + 2
Each value depends only on the previous one, so there will be a simple sequence of numbers. The relation will have a period of no more than 10^6. Since they're all odd, the maximum length is cut in half.
As it turns out, the sequence repeats after 5003 terms, with a period of 5000: 3, 11, 123 do not appear later in the sequence.
So, forget that huge array. Compute the 5003 terms you need. Now for any input number N, you have 3 cases:
(1) N is not divisible by 3: return 0
else N is divisible by 3; call the quotient M
(2) M <= 3: return arr[M]
(3) else, get the needed subscript as m = ((M-3) mod 5000) + 3;
return arr[m]
You can now handle arbitrarily large input.

SIGSEGV Error in Simple Dynamic Programming on SPOJ

I am just beginning with dynamic programming, and I have just attempted a simple question based on DP, on Spoj. Link - http://www.spoj.com/problems/MST1/
Here is the question statement -
On a positive integer, you can perform any one of the following 3
steps.
1.) Subtract 1 from it. ( n = n - 1 )
2.) If its divisible by 2, divide by 2. ( if n % 2 == 0 , then n = n / 2 )
3.) If its divisible by 3, divide by 3. ( if n % 3 == 0 , then n = n / 3 )
Given a positive integer n and you task is find the minimum number of
steps that takes n to one.
Input:
The input contains an integer T (1 ≤ T ≤ 100) number of test cases.
Second line input is N (0 < N ≤ 2*10^7 ) that indicates the positive
number.
Output:
For each case, print the case number and minimum steps.
Here's my code -
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
// Memo Function returns the smallest number of steps possible for integer a
int memo(int a, int mem[]);
int mem[20000010];
int main() {
int t;
scanf("%i", &t);
for(int i = 1; i <= t; i++) {
int n;
scanf("%i", &n);
memset(mem, -1, sizeof(mem));
mem[1] = 0;
printf("Case %i: %i\n", i, memo(n, mem));
}
return 0;
}
int memo(int a, int mem[]) {
if (mem[a] != -1) return mem[a]; // If the value of smallest steps have already been calculated
int r; // Current Lowest number of steps
r = memo(a - 1, mem) + 1;
if (a % 2 == 0) r = min(r, memo(a/2, mem) + 1);
if (a % 3 == 0) r = min(r, memo(a/3, mem) + 1);
mem[a] = r;
return r;
}
I have looked up this error on the internet and here on StackOverflow, and I have found that it may occur when we are trying to access the memory that has not been allocated, for example accessing the 11th element of a 10 element array. But I don't think that's the case here.
Also, I think the upper limit of the question is 2*10^7, also the array is global, so it shouldn't be an issue. Maybe there's some issue in the way I am using the memset function? I really don't know!
Any help will be appreciated! Thanks for reading!
Your DP idea is correct but your code is not working for a large inputs (e.g. 1x10^6, or the upper boundary, 2x10^7).
By changing your code a little, you can pre-compute every answer and then output only the ones you are interested in. It will be not very time-consuming because of the dynamic programming fashion of the problem, i.e., a complex problem can be solved as a combination of one or more previously solved problems.
int main()
{
// Initialize DP array
memset(mem, -1, sizeof(mem));
mem[1] = 0;
// Pre-compute every possible answer
for(int i = 2; i <= 20000000; i++)
mem[i] = memo(i);
// Read the number of test cases
int t;
scanf("%d", &t);
// Print only the desired answer, ie, mem[n]
for(int i = 1; i <= t; i++) {
int n;
scanf("%d", &n);
printf("Case %d: %d\n", i, mem[n]);
}
return 0;
}
I got an ACCEPTED with this approach.
Another tip: since your DP array is global, you do not have to pass it to the DP function every time.

Code for Armstrong numbers not working

Alright please go easy. Just learning C++ and first also question here. I've written a program to list all Armstrong numbers below 1000. While I have read the Wikipedia article on narcissistic numbers, I'm only looking for 3-digit ones. Which means I only care for the sum of the cubes of the digits.
It works by executing a for loop for 1 to 1000, checking whether the indexing variable is armstrong or not using a user defined function and printing it if it is. The user defined function works simply by using a while loop to isolate digits and matching the sum of the cubes to the original number. If it is true, then returns 1 otherwise return 0.
The problem is, I'm getting abolutely no numbers in the output. Only the cout statement in void main() appears and the rest is blank. Tried to debug as much as I could. Complier is Turbo C++. Code-
#include<iostream.h>
#include<conio.h>
int chk_as(int);//check_armstrong
void main()
{
clrscr();
cout<<"All Armstrong numbers below 1000 are:\n";
for(int i=1;i<=1000;i++)
{
if (chk_as(i)==1)
cout<<i<<endl;
}
getch();
}
int chk_as (int n)
{
int dgt;
int sum=0,det=0;//determinant
while (n!=0)
{
dgt=n%10;
n=n/10;
sum+=(dgt*dgt*dgt);
}
if (sum==n)
{det=1;}
else
{det=0;}
return det;
}
The problem is that you are dynamically changing the value of n in your method, but you need its original value to check the result.
Add in a temporary variable, say, t.
int t = n;
while (t!=0)
{
dgt=t%10;
t=t/10;
sum+=(dgt*dgt*dgt);
}
if (sum==n)
// ... etc.
EDIT: Nevermind... this was wrong
while (n!=0)
{
dgt=n%10;
n=n/10;
sum+=(dgt*dgt*dgt);
}
This runs forever as n never reaches 0.
The problem is, that in the end of the loop
while (n!=0)
{
dgt=n%10;
n=n/10;
sum+=(dgt*dgt*dgt);
}
n is 0, so the condition if (sum==n) is never true.
Try something like :
int chk_as (int n)
{
int copy = n;
int dgt;
int sum=0,det=0;//determinant
while (copy!=0)
{
dgt=copy%10;
copy=copy/10;
sum+=(dgt*dgt*dgt);
}
if (sum==n)
{det=1;}
else
{det=0;}
return det;
}
I have given here the program for finding armstrong number of a three digits number.
The condition for armstrong number is,
Sum of the cubes of its digits must equal to the number itself.
For example, 407 is given as input.
4 * 4 * 4 + 0 * 0 * 0 + 7 * 7 * 7 = 407 is an armstrong number.
#include <stdio.h>
int main()
{
int i, a, b, c, d;
printf("List of Armstrong Numbers between (100 - 999):\n");
for(i = 100; i <= 999; i++)
{
a = i / 100;
b = (i - a * 100) / 10;
c = (i - a * 100 - b * 10);
d = a*a*a + b*b*b + c*c*c;
if(i == d)
{
printf("%d\n", i);
}
}
return 0;
}
List of Armstrong Numbers between (100 - 999):
153
370
371
407
Reference: http://www.softwareandfinance.com/Turbo_C/Find_Armstrong_Number.html

Why is my recursiveMinimum function not working?

#include <iostream>
using namespace std;
int recursiveMinimum(int [], int n);
int main ()
{
int theArray[3] = {1,2,3};
cout << recursiveMinimum(theArray, 0);
cout << endl;
return 0;
}
// pass in array and 0 to indicate first element
// returns smallest number in an array
int recursiveMinimum (int anArray[], int n) // nth element is smallest element in anArray
{
while (anArray[n+1] != NULL)
{
int smallest = n;
if (anArray[n+1] <= anArray[n])
smallest = n + 1;
//if last element has not been reached
return recursiveMinimum(anArray, smallest);
}
}
My function exits, but it doesn't return anything. I tried to set the base case to when the outside of the array is reached. The return 0 line in main is reached so I'm pretty sure the base case in my function is being reached.
Here is the working function:
#include <iostream>
using namespace std;
int recursiveMinimum(int a[],int min,int index,int size);
int main()
{
int a[6] = {8, 2, 55, 3, 11, 9};
cout << recursiveMinimum(a,a[0],1,6) << endl;
return 0;
}
// pass in the array, the first element,
// 1 to indicate 2nd element, and the number of elements
int recursiveMinimum(int a[],int min,int i,int size)
{
if(i == size )
return min;
else if(i < size)
{
if(a[i] < min)
recursiveMinimum(a,a[i], i + 1, size);
else
recursiveMinimum(a,min, i + 1, size);
}
}
Thank you to everyone who helped. Due to time constraints I sent out a SOS (Stack Overflow distress Signal), however next time I will definitely step through the debugger prior to asking a question.
Have you stepped through this in a debugger? It should become fairly obvious when you do.
You are recursing within the while loop:
while( condition )
recursive call
while( condition )
recursive call
.
.
.
Instead what you probably were thinking was
if( condition )
recursive call
recursive call
recursive call
you see? Get rid of the while and replace it with an "if" statement.
You need to have an end case with a recursive function.
At the moment, your function always returns itself. This will recurse until the stack runs out. You need to have a check that says "I'm done", which will return a value rather than the result of another function call.
Because your while loop never terminates. Why are you sure anArray[n+1] will ever be NULL?
You never break your recursion. Actually I wonder that this compiles as your function doesn't even have a defined return value in case it reaches the end. Also using while there seems unnecessary as the function execution stops after the return anyway.
Instead of
int recursiveMinimum(int array[], int n);
I think that recursiveMinimum should be defined as
int recursiveMinimum(int array[], int index, int length);
with the intention that recursiveMinimum will return the minimum value in array between indexes index and length (i.e., min array[i] where i in [index, length)). Of course, you want to define this recursively. So then I would note that the minimum value in array between indexes index and length is
min(array[index], recursiveMinimum(array, index + 1, length));
Of course, there are boundary cases (such as when index = length - 1). In this case you would just return array[index] as the minimum.
Hope this helps. Let me know if this does not make sense.
You're misunderstanding the point of a recursive function. If a certain condition is true, then you return the result of a call to the recursive function, otherwise you return some other value. For example, here is a recursive definition of the factorial function (e.g. 5!, or "5 factorial", is 5*4*3*2*1, which is 125):
int
factorial (int n)
{
if (n == 1)
return n;
return (n * factorial (n - 1));
}
How it works:
If n is 1, then return 1 since 1! is 1.
Otherwise, return n multiplied by one less than n.
For example, if n is 5, then the return value is the result of the expression 5 * factorial (5 - 1), which is the same as 5 * factorial (4). Of course, the same thing happens again since it's a recursive function and 4 is not 1. So you end up with 5 * factorial (4), which is the same as 5 * (4 * factorial (4 - 1)), or 5 * (4 * factorial (3)).
You should be able to see the pattern now and how the factorial function works. Your recursiveMinimum function should adhere to the same general idea -- if something is true (or not true), return the result of a call the function (possibly with some additional things like the value n inside the factorial function needs to be multiplied by the result of the factorial function), else return a certain value and code the function to handle it appropriately. In other words, you need a "final" exit condition, such as the n == 1 condition in the factorial function above.
Good luck!
int recursiveMinimum(int a[],int min,int index,int size)
{
if(index == size )
return min;
else if(i < size)
{
if(a[i] < min)
recursiveMinimum(a,a[i],++index,size);
else
recursiveMinimum(a,min,++index,size);
}
}
int main()
{
int a[] = {1,2,3,0,-4};
int min = recursiveMinimum(a,a[0],1,5));
return 0;
}
When you use recursion make sure that you must put some exit condition to end it ,otherwise you will have in infinite recursion and you program will hang.
I think finding minimum is more efficient,easy and simple using iteration rather than recursion.