Recursive solution for 3n+1 - c++

I just like to do simple recursion.
For a number if it is even then it'll approach to (number/2) and if odd then to (3*number+1). How many time it'll occur to reach 1.
for 10
10-> 5-> 16-> 8-> 4 -> 2 ->1
total process 6
long arr[10000];
long dp(int n)
{
if(n==2|| n==1) return 1;
if(arr[n]) return arr[n];
if(n%2==0) return arr[n]=1+dp(n/2);
else if(n%2==1) return arr[n]=1+dp(3*n+1);
return arr[n];
}
I've created function like this one and for some input like 999 or 907 causes segmentation fault.
I wanna know why?
And if I increase array size then its output correctly.
I wanna know why too?
Why its depending on array size as I've taken long as array element data type so it should output correctly for those input?

with 999, you reach 11392
with 907, you reach 13120
and those numbers are out of bound.
Live example

You are indexing the array out of bounds
For the inputs you are using, the variable n will exceed the array size 10000 during execution. This causes the program to access memory beyond its boundaries, resulting in a segmentation fault.
If you're trying to memoize the function, I'd suggest using std::map instead of a fixed array. This is an associative array which stores key-value pairs—in this case, each memoized input-output pair—and can quickly retrieve the value associated with a given key. Maps are ideally suited for this application as they can store this data using only as much memory as is actually necessary, automatically growing as needed.
You could also use std::vector, though this is not recommended. Vectors are like arrays, but they can be resized dynamically, avoiding the problem of indexing out of bounds. The drawback with this approach is that for certain inputs, a very large amount of memory may be required, possibly several gigabytes. If the program is compiled to a 32-bit binary rather than to a 64-bit binary, the program may crash at runtime when it fails to allocate enough memory for the vector.
Implementation using map
#include <iostream>
#include <map>
using namespace std;
long long dp(unsigned long long);
int main() {
unsigned long long n;
while(true) {
cout << "Enter a number, or 0 to exit: ";
cin >> n;
if(!cin) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cerr << "Invalid input, please try again." << endl;
continue;
}
if(n == 0)
return 0;
else
cout << dp(n) << endl;
}
return 0; // Unreachable
}
long long dp(unsigned long long n) {
static map<long long, long long> memo;
if(n == 2 || n == 1) return 1;
if(memo[n]) return memo[n];
if(n % 2 == 0) return memo[n] = 1 + dp(n / 2);
else if(n % 2 == 1) return memo[n] = 1 + dp(3 * n + 1);
return memo[n];
}
Implementation using vector
#include <iostream>
#include <vector>
using namespace std;
long long dp(unsigned long long);
int main() {
unsigned long long n;
while(true) {
cout << "Enter a number, or 0 to exit: ";
cin >> n;
if(!cin) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cerr << "Invalid input, please try again." << endl;
continue;
}
if(n == 0)
return 0;
else
cout << dp(n) << endl;
}
return 0; // Unreachable
}
long long dp(unsigned long long n) {
static vector<long long> arr;
if(arr.size() <= n)
arr.resize(n + 1);
if(n == 2 || n == 1) return 1;
if(arr[n]) return arr[n];
if(n % 2 == 0) return arr[n] = 1 + dp(n / 2);
else if(n % 2 == 1) return arr[n] = 1 + dp(3 * n + 1);
return arr[n];
}

The segmentation fault comes from overflowing the array. How about you do something like the following?
void rec(int n, int* steps) {
++(*steps);
printf("%d\n", n);
// termination step if 'n' equals 1
if(n == 1)
return;
if (n % 2 == 0)
rec(n/2, steps);
else
rec(3*n+1, steps);
}
int main(void) {
int steps = 0;
rec(10, &steps);
printf("Steps = %d\n", steps);
return 0;
}
Output:
10
5
16
8
4
2
1
Steps = 7
The code presented here agrees (of course) with Jarod's answer.

You are overflowing the array because the sequence value exceeds 9999.

If all you want to know is the number of processes that it takes, you should not be using array storage.
int numProcesses = 0;
int hailstone(int n) {
if (n == 1) {
return 1;
} // base case
++numProcesses; // if it wasn't the base case the method will do some work so increment numProcesses
if (n % 2 == 0) {
return hailstone(n / 2);
} // n is even
else {
return hailstone(3 * n + 1);
} // n is odd
}
This is untested but I think it should work, and after it finally returns numProcesses should equal the number of times the method was called (so long as it was not called with a parameter of 1).

Related

why am I getiing 0 as a result,I want the return value as the result?

I want the result to be the returned value from the mystery function,but the result is always 0 .but I want the program to return a value that's collected from the mystery function
#include <iostream>
using namespace std;
int Mystery(int n)
{
// int k;
if (n <= 1)
{
return 0;
}
else
{
int k = n;
for (int i = 1; i <= n; i++)
{
k = k + 5;
}
cout << ((k * (n / 2)) + (8 * (n / 4)));
cout << "\n ";
return ((k * Mystery(n / 2)) + (8 * Mystery(n / 4)));
}
}
int main(void)
{
int i, n;
cout << "Enter n:"; //array size
cin >> n;
int result = Mystery(n);
cout << "The result is " << result;
return 0;
}
Let's desk check what happens when you call Mystery(2). The final return value is:
((k* Mystery(n/2)) + (8* Mystery(n/4)))
We know that n == 2 so let's substitute that:
((k* Mystery(1)) + (8* Mystery(0 /* by integer division of 2/4 */)))
This will call the function recursively twice with the respective arguments 1 and 0. But we know that the terminating case n <= 1 returns 0, so we can substitute that:
((k* 0) + (8* 0))
Anything multiplied by zero is zero, so this reduces to 0 + 0 which is also zero. It doesn't even matter what k is.
Quite simply, the terminating case for this recursion mandates that the result is always zero.
In the terminating case the return value is zero.
In the recursive case, the recursive call result is multiplied with another value to produce the return value.
Therefore, the result is always going to be zero for any n.
I'm not sure exactly how this function is supposed to work as you have not explained that, but changing the terminating case to return 1; may solve the problem.
I don't expect which result you want, but I think you can get write result when you correct conditions like
if (n == 0)
return 0;
if (n == 1)
return 1;
I hope it returns the right result.

The Coursera autograder gives me Unknown Signal 11

I'm in a class in Algorithms and now we are taking Greedy Algorithms.
Two of my solutions output "Uknown Signal 11" on some of the test cases.
However, I drove my program to the limit with the largest inputs possible.
It works just fine on my PC. However on Coursera's grader, it throws tgghis cryptic message of Unknown Signal 11.
Will this go away if I change to Python for example?
Here's the first code exhibiting the problem:
#include <iostream>
#include <utility>
#include <algorithm>
using namespace std;
bool sortAlg(pair<double, pair<uint64_t,uint64_t>> item1, pair<double,
pair<uint64_t,uint64_t>> item2)
{
return (item1.first >= item2.first);
}
int main()
{
uint64_t n, index = 0;
double W, val;
cin >> n >> W;
pair<double, pair<uint64_t,uint64_t>> items[n];
for (int i=0; i <n; i++)
{
cin >> items[i].second.first >> items[i].second.second;
items[i].first = (double)items[i].second.first / (double)items[i].second.second;
}
sort(items,items+n, sortAlg);
while(W > 0 && n > 0)
{
if (items[index].second.second <= W)
{
val += items[index].second.first;
W -= items[index].second.second;
index++;
n--;
}
else
{
val += items[index].first * W;
W = 0;
index++;
n--;
}
}
printf("%.4f",val);
return 0;
}
I think this has to do with the while loop, but I can't think of anything where the program will make an out of bounds array call using index.
Anyways it is a fractional knapsack implementation.
Here's the second code which also gives unknown signal 11:
#include <iostream>
#include <string>
#include<vector>
#include <algorithm>
#include <utility>
using namespace std;
bool sortAlg(string num1, string num2)
{
if (num1[0] > num2[0]) return true;
else if (num1[0] < num2[0]) return false;
else
{
if (num1.size() == 1 && (num1[0] > num2[1])) return true;
else if (num1.size() == 1 && (num1[0] < num2[1])) return false;
else if (num2.size() == 1 && (num1[1] > num2[0])) return true;
else if (num2.size() == 1 && (num1[1] < num2[0])) return false;
else if (num1 == "1000" || num2 == "1000") return (num1 < num2);
else
{
if (num1.size() == num2.size()) return (num1 > num2);
else
{
return (num1[1] > num2[1]);
}
}
}
}
int main()
{
string num;
int n, n2 = 1;
cin >> n;
//int numbers[n];
vector<string> numbers2;
for (int i =0; i <n; i++)
{
num = to_string(n2);
cout << num << endl;
numbers2.push_back(num);
n2 += 10;
}
sort(numbers2.begin(), numbers2.end(), sortAlg);
for (auto number : numbers2)
{
cout << number;
}
return 0;
}
I suspect the sortAlg function used in sort function, but on my PC it is relatively fast. And the problem statement required some weird sorting.
The problem was given a set of numbers, arrange them to make thebiggest number possible.
If given 9, 98, 2, 23, 21 for example it should give me 99823221.
(9 > 98 > 23 > 2 > 21)
So I sort by the first digit then the next and so on.
You have a StackOverflow error.
The necessary stack size depends on the depth of your recursion, the number of parameters of your recursive function and on the number of local variables inside each recursive call.
In Python, you have to set the necessary stack size. The starter files provided in Python 3 would have the sample below:
import threading
sys.setrecursionlimit(10 ** 6) # max depth of recursion
threading.stack_size(2 ** 27) # new thread will get stack of such size
...
threading.Thread(target=main).start()
Note how the stack_size is allocated.
It's just an additional information related to Coursera grader.
In the week 6 the same course , if you declare a 2D array for the dynamic programming problem, the grader gives the Signal 11 error and program fails even if it is working perfectly fine on local machine .
Solution to above problem - replace 2-D array by 2D vector (in case of C++) and submit again. The grader will accept the code solution and no signal 11 error will be thrown.

Print all prime number lower than n in C++ ( file crash )

I wrote a C++ program that prints all prime numbers lower than n, but the program keeps crashing while executing.
#include <iostream>
using namespace std;
bool premier(int x) {
int i = 2;
while (i < x) {
if (x % i == 0)
return false;
i++;
}
return true;
}
int main() {
int n;
int i = 0;
cout << "entrer un entier n : ";
cin >> n;
while (i < n) {
if (n % i == 0 && premier(i))
cout << i;
i++;
}
;
}
As Igor pointed out, i is zero the first time when n%i is done. Since you want only prime numbers and the smallest prime number is 2, I suggest you initialise i to 2 instead of 0.
You want to print all prime numbers less than n and has a function to check primality already.
Just
while (i < n){
if ( premier(i) == true )
cout<<i;
i++;
}
And while printing, add a some character to separate the numbers inorder to be able to distinguish them like
cout<<i<<endl;
P.S: I think you call this a C++ program. Not a script.
Edit: This might interest you.

Find Largest Prime Factor - Complexity of Code

I tried a code on a coding website to find the largest prime factor of a number and it's exceeding the time limit for the last test case where probably they are using a large prime number. Can you please help me to reduce the complexity of the following code?
int main()
{
long n;
long int lar, fact;
long int sqroot;
int flag;
cin >> n;
lar=2, fact=2;
sqroot = sqrt(n);
flag = 0;
while(n>1)
{
if((fact > sqroot) && (flag == 0)) //Checking only upto Square Root
{
cout << n << endl;
break;
}
if(n%fact == 0)
{
flag = 1;
lar = fact;
while(n%fact == 0)
n = n/fact;
}
fact++;
}
if(flag == 1) //Don't display if loop fact reached squareroot value
cout << lar << endl;
}
Here I've also taken care of the loop checking till Square Root value. Still, how can I reduce its complexity further?
You can speed things up (if not reduce the complexity) by supplying a hard-coded list of the first N primes to use for the initial values of fact, since using composite values of fact are a waste of time. After that, avoid the obviously composite values of fact (like even numbers).
You can reduce the number of tests by skipping even numbers larger than 2, and stopping sooner if you have found smaller factors. Here is a simpler and faster version:
int main() {
unsigned long long n, lar, fact, sqroot;
cin >> n;
lar = 0;
while (n && n % 2 == 0) {
lar = 2;
n /= 2;
}
fact = 3;
sqroot = sqrt(n);
while (fact <= sqroot) {
if (n % fact == 0) {
lar = fact;
do { n /= fact; } while (n % fact == 0);
sqroot = sqrt(n);
}
fact += 2;
}
if (lar < n)
lar = n;
cout << lar << endl;
return 0;
}
I am not sure how large the input numbers may become, using the larger type unsigned long long for these computations will get you farther than long. Using a precomputed array of primes would help further, but not by a large factor.
The better result I've obtained is using the function below (lpf5()). It's based on the primality() function (below) that uses the formulas 6k+1, 6k-1 to individuate prime numbers. All prime numbers >= 5 may be expressed in one of the forms p=k*6+1 or p=k*6-1 with k>0 (but not all the numbers having such a forms are primes). Developing these formulas we can see a sequence like the following:
k=1 5,7
k=2 11,13
k=3 17,19
k=4 23,25*
k=5 29,31
.
.
.
k=10 59,61
k=11 65*,67
k=12 71,73
...
5,7,11,13,17,19,23,25,29,31,...,59,61,65,67,71,73,...
We observe that the difference between the terms is alternatively 2 and 4. Such a results may be obtained also using simple math. Is obvious that the difference between k*6+1 and k*6-1 is 2. It's simple to note that the difference between k*6+1 and (k+1)*6-1 is 4.
The function primality(x) returns x when x is prime (or 0 - take care) and the first divisor occurs when x is not prime.
I think you may obtain a better result inlining the primality() function inside the lpf5() function.
I've also tried to insert a table with some primes (from 1 to 383 - the primes in the first 128 results of the indicated formulas) inside the primality function, but the speed difference is unappreciable.
Here the code:
#include <stdio.h>
#include <math.h>
typedef long long unsigned int uint64;
uint64 lpf5(uint64 x);
uint64 primality(uint64 x);
uint64 lpf5(uint64 x)
{
uint64 x_=x;
while ( (x_=primality(x))!=x)
x=x/x_;
return x;
}
uint64 primality(uint64 x)
{
uint64 div=7,f=2,q;
if (x<4 || x==5)
return x;
if (!(x&1))
return 2;
if (!(x%3))
return 3;
if (!(x%5))
return 5;
q=sqrt(x);
while(div<=q) {
if (!(x%div)) {
return div;
}
f=6-f;
div+=f;
}
return x;
}
int main(void) {
uint64 x,k;
do {
printf("Input long int: ");
if (scanf("%llu",&x)<1)
break;
printf("Largest Prime Factor: %llu\n",lpf5(x));
} while(x!=0);
return 0;
}

Recursive/iterative functions

I'm having a bit of a hard time creating a function, using iteration and recursion to find the sum of all even integers between 1 and the number the user inputs. The program guidelines require a function to solve this three ways:
a formula
iteration
recursion
This is what I have so far:
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
void formulaEvenSum(int num, int& evenSum)
{
evenSum = num / 2 * (num / 2 + 1);
return;
}
void loopEvenSum(int num, int& evenSum2)
{
}
int main()
{
int num, evenSum, evenSum2;
cout << "Program to compute sum of even integers from 1 to num.";
cout << endl << endl;
cout << "Enter a positive integer (or 0 to exit): ";
cin >> num;
formulaEvenSum(num, evenSum);
loopEvenSum(num, evenSum2);
cout << "Formula result = " << evenSum << endl;
cout << "Iterative result = " << evenSum2 << endl;
system("PAUSE");
return 0;
}
Using iteration to find the sum of even number is as given below.
void loopEvenSum(int num, int &evenSum2)
{
evenSum2=0;
for (i=2;i<=num;i++)
{
if(i%2==0)
evenSum2+=i;
}
}
The following code though not the most efficient can give you an idea how to write a recursive function.
void recursiveEvenSum(int num,int &evenSum3,int counter)
{
if(counter==1)
evenSum3=0;
if(counter>num)
return;
if(counter%2==0)
evenSum3+=counter;
recursiveEvenSum(num,evenSum3,counter+1);
}
Now you can call recursiveEvenSum(...) as
int evenSum3;
recursiveEvenSum(num,evenSum3,1);
You should be able to build an iterative solution using a for loop without too much problem.
A recursive solution might take the form:
f(a)
if(a>0)
return a+f(a-1)
else
return 0
f(user_input)
You have to differentiate between a case where you "dive deeper" and one wherein you provide an answer which doesn't affect the total, but begins the climb out of the recursion (though there are other ways to end it).
An alternative solution is a form:
f(a,sum,total)
if(a<=total)
return f(a+1,sum+a,total)
else
return sum
f(0,0,user_input)
The advantage of this second method is that some languages are able to recognise and optimize for what's known as "tail recursion". You'll see in the first recursive form that it's necessary to store an intermediate result for each level of recursion, but this is not necessary in the second form as all the information needed to return the final answer is passed along each time.
Hope this helps!
I think this does it Don't forget to initialize the value of evenSum1, evenSum2 and evenSum3 to 0 before calling the functions
void loopEvenSum(int num, int& evenSum2)
{
for(int i = num; i > 1; i--)
if(i%2 == 0)
evenSum2+=i;
}
void RecursiveEvenSum(int num, int & evenSum3)
{
if(num == 2)
{
evenSum3 + num;
return;
}
else
{
if(num%2 == 0)
evenSum3+=num;
num--;
RecursiveEvenSum(num, evenSum3);
}
}
void loopEvenSum(int num, int& evenSum2)
{
eventSum2 = 0;
for(int i = 1 ; i <= num; i++){
(i%2 == 0) eventSum += i;
}
}
void recurEvenSum(int num, int& evenSum3)
{
if(num == 1) return;
else if(num % 2 == 0) {
eventSum3 += num;
recurEvenSum(num-1, eventSum3);
}
else recurEvenSum(num-1, eventSum3);
}
btw, you have to initialize evenSum to 0 before calling methods.
the recursive method can be much simpler if you return int instead of void
void iterEvenSum(int num, int& evenSum2)
{
evenSum2 = 0;
if (num < 2) return;
for (int i = 0; i <= num; i+=2)
evenSum2 += i;
}
int recurEvenSum(int num)
{
if (num < 0) return 0;
if (num < 4) return 2;
return num - num%2 + recurEvenSum(num-2);
}
To get the sum of all numbers divisible by two in the set [1,num] by using an iterative approach, you can loop through all numbers in that range, starting from num until you reach 2, and add the number of the current iteration to the total sum, if this is divisible by two.
Please note that you have to assign zero to evenSum2 before starting the loop, otherwise the result will not be the same of formulaEvenSum().
void loopEvenSum(int num, int& evenSum2)
{
assert(num > 0);
evenSum2 = 0;
for (int i=num; i>=2; --i) {
if (0 == (i % 2)) {
evenSum2 += i;
}
}
}
To get the same result by using a recursive approach, instead of passing by reference the variable that will hold the sum, i suggest you to return the sum at each call; otherwise you'll need to hold a counter of the current recursion or, even worse, you'll need to set the sum to zero in the caller before starting the recursion.
int recursiveEventSum(int num)
{
assert(num > 0);
if (num == 1) {
return 0;
} else {
return ((num % 2) ? 0 : num) + recursiveEventSum(num-1);
}
}
Please note that, since you get an even number only if you subtract two (not one) from an even number, you could do optimisation by iterating only on those numbers, plus eventually, the first iteration if num was odd.