Function: smallest positive integer - c++

#include <iostream>
using namespace std;
int enough(int goal)
{
int C { };
int i { };
if (goal > 1)
{
while (((C += i) <= goal) && ((goal - i) <= (i + 1)))
{
i += 1;
}
}
else
{
i = 1;
}
return i;
}
int main()
{
cout << enough(21);
return 0;
}
So the purpose of this function is for it to return the smallest positive integer that can be summed consecutively from 1 before the cumulative sum becomes greater than the parameter "goal".
So, for example:
cout << enough(9) << endl;
will print 4 because 1+2+3+4 > 9 but 1+2+3<9
cout << enough(21) << endl;
will print 6 'cause 1+2+ . . .+6 > 21 but 1+2+ . . . 5<21
cout << enough(-7) << endl;
will print 1 because 1 > -7 and 1 is the smallest positive integer
cout << enough(1) << endl;
will print 1 because 1 = 1 and 1 is the smallest positive integer
My logic at first was using just while ((C += i) <= goal), but that went wrong, for example, for the parameter 21, where you get C = 20, which passes the test and ends up in i being augmented by 1 (resulting in the return value i = 7, which is clearly wrong).
Therefore I decided to create a test which tested both C and i, but that went wrong because the code isn't considering goal - i and i + 1 as separate tests for the while circuit, but I believe it is actually altering the value of ints goal and i, which screws everything up.
Any ideas where I went wrong?

Your approach is unnecessarily verbose. There is a closed-form (i.e. O(1)) solution for this.
The sum S of the arithmetic progression 1, 2, ..., n is
S = n * (n + 1) / 2
Rearranging this (completing the square), rejecting the spurious root, and rounding appropriately to fit the requirements of the question yields the result
n = std::ceil((-1 + std::sqrt(1 + 8 * S)) / 2)
This will not work for negative n, and possibly 0 too depending on the specific (and unspecified) requirements.
Or if you must use an O(N) approach, then
int enough(int goal){
int i = 0;
for (int total = 0; (total += ++i, total) < goal; );
return i;
}
will do it, which returns 1 for goal <= 1.

You could perhaps try to simplify your original O(N) approach by only having one condition in your while-loop, i.e., no &&:
#include <iostream>
using namespace std;
int enough(int goal)
{
if (goal <= 0)
{
return 1;
}
int total{};
int i{};
while (total < goal)
{
total += ++i;
}
return i;
}
int main()
{
cout << "enough(9): " << enough(9) << endl;
cout << "enough(21): " << enough(21) << endl;
cout << "enough(-7): " << enough(-7) << endl;
cout << "enough(1): " << enough(1) << endl;
cout << "enough(0): " << enough(0) << endl;
return 0;
}
Output:
enough(9): 4
enough(21): 6
enough(-7): 1
enough(1): 1
enough(0): 1

Related

Number of even divisors using square root

I'm solving an problem where it need to get the difference between the number of even and odd divisors ,and i need to use sqrt() function because the limit of the number is 10^9 so looping on the whole number is not an option cause of the time limit exceed.
this a function I tried to make but it doesn't work perfectly on all number.
Ex. 4 & 48745.
Case 4 : should output 2 even divisors {2,4} and 1 odd divisor {1} -- the below function output 3 even 1 odd
Case 48745 :should output 0 even divisors and 4 odd divisors {1,5,9749,48745} -- the below function output 2 even 2 odd
int di(int x)
{
int even=0,odd=0;
for(int i=1;i<=sqrt(x);i++)
{
if(x%i==0)
{
if(i%2)
odd++;
else
even++;
if(x/i %2==0 && x/i!=i)
even++;
else if(x/i!=i)
odd++;
}
}
return even-odd;
}
Try more simple code:
#include <iostream>
#include <cmath>
int divdiff(int x)
{
unsigned int even = 0;
unsigned int odd = 0;
const unsigned int sqrtx = std::sqrt(x);
for (int i = 1 ; i <= sqrtx ; ++i)
{
if (x % i == 0)
{
if (i % 2 == 0)
{
++even;
}
else
{
++odd;
}
}
}
even *= 2;
odd *= 2;
if (x == sqrtx * sqrtx)
{
if (x % 2 == 0)
{
--even;
}
else
{
--odd;
}
}
std::cerr << __func__ << '(' << x << "): even=" << even << ", odd=" << odd << std::endl;
return even - odd;
}
int main()
{
std::cout << divdiff(2*2) << std::endl;
std::cout << divdiff(2*3) << std::endl;
std::cout << divdiff(3*3) << std::endl;
std::cout << divdiff(7*11*13*17*23) << std::endl;
}

find the each number of 4 digit of user input and count it using recursion

I have with my code. This is about recursion. I have to create function digitAppear( int findDigit, int value) where value is the user input, and findDigit is single digit number ranging from 0 to 9. The function read user input and return each digit number from the user input and count how many times each digit number occurs in the user input. For example, if I type 1234 then the output say 1 appear 1 time, 2 appear 1 time and so on (I hope my explanation is clear) The problem is the only run once and can only return 1 value.
#include <iostream>
using namespace std;
int countOccurence(int, int);
int main()
{
int findDig;
int value;
int n = 0;
cout << "Please enter a positive number: " << endl;
cin >> value;
cout << "The value is " << value << endl;
while ((value < 0) || (value > 9999))
{
cout << "Invalid value. Please try again!" << endl;
cout << "Please enter a positive number: " << endl;
cin >> value; //you need this here, otherwise you're going to be stuck in an infinite loop after the first invalid entry
}
//process the value
for (findDig = 0; findDig < 9; findDig++)
{
cout << endl;
cout << cout << "the " << findDig << "appear in digit " << value << " is " << countOccurence(findDig, value) << " times" << endl;
}
//countOccurance(findDig, value);
//cout
}
int countOccurence(int findDig, int value)
{
int n = value;
while( n > 10 )
{
int a = n / 10; //eliminate the right most integer from the rest
int aa = n % 10; //separate the right most integer from the rest
int b = a / 10; //eliminate the second integer from the rest
int bb = a % 10; //separate the second integer from the rest
int c = b / 10; // eliminate the third integer from the rest
int cc = b % 10; //separate the third integer from the rest
for (findDig = 0; findDig < 9; findDig++)
{
int i = 0;
if (findDig == aa) // see if the findDigit value is equal to single digit of b;
{
i += 1;
} else
{
i += 0;
}
return i;
if (findDig == bb)
{
i += 1;
} else
{
i += 0;
}
return i;
if (findDig == cc)
{
i += 1;
} else
{
i += 0;
}
return il;
}
}
}
The problem is my function countOccurence() doesn't seems right. I wonder if there a way to do it. I have been stuck with this for days and I really appreciate your input, thank you.
To use recursion, you must think about the problem in a different way.
The easiest way of thinking about how you could incorporate recursion into the function is the process of 'peeling off' each number.
A very simple way of doing this is by looking at the first/last digit in the number, compute that, then call itself on the remainder of the number.
Hopefully you can figure out the code from there.
If you mean that function digitAppear itself has to be recursive then it can look the following way as it is shown in the demonstrative program below
#include <iostream>
#include <cstdlib>
size_t digitAppear( int findDigit, int value )
{
return ( std::abs( value ) % 10u == std::abs( findDigit ) ) +
( ( value /= 10 ) ? digitAppear( findDigit, value ) : 0 );
}
int main()
{
int i = 0;
for ( int x : { 0, 11111, 1234, 34343 } )
{
std::cout << "There are " << digitAppear( i, x )
<< " digit " << i
<< " in number " << x
<< std::endl;
++i;
}
return 0;
}
The program output is
There are 1 digit 0 in number 0
There are 5 digit 1 in number 11111
There are 1 digit 2 in number 1234
There are 3 digit 3 in number 34343
Of course you may rewrite function main as you like for example that it would count each digit in a number.

Classifying digits of an integer value

I spent a day on this code for count even and zero and odd numbers
From long datatype I used a function to send data. Here is the code
#include <iostream>
using namespace std;
void digitCount(long long int &num);
int main ()
{
long long int num;
cout <<"Enter any No. " <<endl;
cin >>num;
cout <<endl;
digitCount(num);
return 0;
}
void digitCount(long long int &num)
{
int e = 0, z = 0, o = 0, x = 0;
for (int i = 0; i <= num; i++)
{
x= num % 10;
if(x == 0)
{
++z;
num = num / 10;
}
else if(x%2==1)
{
++o;
num = num / 10;
}
else
{
++e;
num = num / 10;
}
}
cout << "No of zeros Digits = " << z<< endl;
cout << "No of odd Digits = " << o << endl;
cout << "No of Even Digits = " << e << endl;
}
the problem is when I count odd numbers there is a number missed
for example when i input : 12345
the result is
no of even : 2
no of odd : 2 (should be 3)
no of zero : 0
and here the question :
Write a function that takes as parameter an integer (as a long value) and returns the number of odd, even, and zero digits. Also write a program to test your function. Use pass by reference method.
Instead of the for loop you should use:
while (num > 0)
You're constantly changing num and when it gets to 1 (in your 12345 example), i is at 3. I also modified your digitcount to demonstrate some decent formatting for readable code.
void digitCount(long long int &num) {
int e(0), z(0), o(0), x(0);
while (num > 0) {
x = num % 10;
if (x == 0) {
z++;
}
else if (x % 2 == 1) {
o++;
}
else {
e++;
}
num /= 10;
}
cout << "No of zeros Digits = " << z << endl;
cout << "No of odd Digits = " << o << endl;
cout << "No of Even Digits = " << e << endl;
}
If you believe this solves your problem && is the best answer, please click the checkmark next to this answer. Thanks

Recursion help in C++

The assignment is Design and Develop a C++ program to list the first N terms of the Fibonacci series.
The output should look like this:
N=2 1,1
N=2 1,1
N=3 1,1,2
N=4 1,1,2,3
N=5 1,2,3,5
N=6 ....
My problem is that I have written the recursive function below but I'm not sure how to format it so it outputs to screen in the manner above.
#include <iostream>
using namespace std;
//Function Prototype
int fib(int);
int main()
{
for (int x = 0; x < 15; x++)
cout << fib(x) << " ";
cin.get();
cin.get();
return 0;
}
//Definition of fib
int fib(int n)
{
//Return 1 when n is 0
if ( n <= 0 )
return 0;
else if (n == 1)
return 1;
else
return fib(n-1) + fib(n-2);
}
Could someone shed some light on how to get this accomplished?
Thank you.
if you don't care too much about efficiency, a double loop will do
for (int x = 2; x < 15; x++) {
cout << "N = " << x << " ";
for (int y = 2; y <= x; y++)
cout << fib(y) << " ";
cout << endl;
}
How to format?
You have a good start.
Try this as a next step...
for (int x = 0; x < 15; x++)
cout << x << "=" << fib(x) << " " << std::endl;
cin.get();
In my system, I can add to the cout line, compile, and review the output in < 10 seconds. Fast turn around and practice (for you) are your friends.
I would take a different approach. I'd save the already computed Fibonacci values so they are not computed them over and over again, like in a map, and than using that map to print the values.
std::map<int, int> fibs;
int fib(int const n)
{
auto p = fibs.find(n);
if(p != fibs.end())
return p->second;
int f = 1;
if (n > 1)
{
f = fib(n-1) + fib(n-2);
}
fibs[n] = f;
return f;
}
You can then loop through the computed values like this:
for(int n = 0; n < 10; ++n)
{
fib(n);
std::cout << "N=" << n << " ";
for(int i = 0; i <= n; ++i)
std::cout << fibs[i] << ",";
std::cout << std::endl;
}
Since it all does is print the fibonacci number, and the ones before, you just need to add them to your output ...
You can either have an aggregating string that you pass along, that will hold all the temp values, or just call another method that will have temp outputs. (mind you, it's not very efficient though :)
int fib_verbose(int n)
{
//Return 1 when n is 0
if ( n <= 0 )
return 0;
else if (n == 1) {
return 1;
}
else {
int smaller = fib(n-2);
int larger = fib(n-1);
cout << smaller << " " << larger << endl;
return smaller + larger;
}
}
You'll have to sort out the spaces, and formatting, but that's the gist.
Edit:
As per agbinfo comment: removed the 1 printing, and also storing the variables so we don't need to call them twice. (Still, for efficiency, look at Marius's answer :) ).
Here's an example that doesn't recompute values when calling fib for a single value. You can combine Marius's idea to compute the values once even on multiple runs.
The trick is that fib(unsigned&, unsigned) will return the previous fibonacci it has already computed.
#include <iostream>
using namespace std;
unsigned fib(unsigned& m, unsigned n)
{
if (n==0) {
return 0;
}
if (n==1) {
m = 0;
// cout << "0,"; // uncomment if sequence should start with a 0
return 1;
}
unsigned prev;
m = fib(prev, n-1);
cout << m << ",";
return m+prev;
}
unsigned fib(unsigned n) {
unsigned prev;
unsigned f = fib(prev, n);
cout << f;
return f;
}
int main() {
for (unsigned i=2; i<13; i++) {
cout << "N=" << i << " ";
fib(i);
cout << endl;
}
return 0;
}
Will printout:
N=2 1,1
N=3 1,1,2
N=4 1,1,2,3
N=5 1,1,2,3,5
N=6 1,1,2,3,5,8
N=7 1,1,2,3,5,8,13
N=8 1,1,2,3,5,8,13,21

UVA 3n+1 (prob 100) wrong answer but all the test cases are passed

I've seen some questions about 3n+1 problem on stackoverflow and etc and tried to fix the mentioned tips to get the code correct. for example now I check if a > b or not. or i use long long instead of simple int. but still get wrong answer. what is wrong with my answer?
my code:
#include <iostream>
using namespace std;
int count_steps(long long int num)
{
int counter = 1;
while(num != 1)
{
if (num % 2 == 1)
num = 3*num + 1;
else
num /= 2;
counter++;
}
return counter;
}
int max_between(long long int a , long long int b)
{
int max=0,step;
for(long long int i = a; i <= b; i++)
{
if ((step = count_steps(i)) > max)
max = step;
}
return max;
}
int main()
{
int max=0,a,b,step;
cin >> a;
cin >> b;
if (a >= b)
cout << a << ' ' << b << ' ' << max_between(b,a) << endl;
else
cout << a << ' ' << b << ' ' << max_between(a,b) << endl;
return 0;
}
test cases:
1 10 (input)
1 10 20 (output)
900 1000 (input)
900 1000 174 (output)
1 1000000 (input)
1 1000000 525 (output)
1000000 1 (input)
1000000 1 525 (output)
Some remarks to your code:
You're reading a and b as int, though using them as long long int in the methods. That's nonsense, read them as the type they are going to be used.
Although unlikely, you might experience overflows. To avoid that, you can double your range of integers by using unsigned long long.
Mathematically speaking, you're doing too much.
For an odd integer n = 2 k + 1, the result 3 n + 1 will always be even: 3 n + 1 = 3(2 k + 1) + 1 = 6k + 4. Therefore you can combine the case for odd n with the following division by two. The result of that would be 3 k + 2 which is k + 1 greater than n. Using integer arithmetic in C++, this is can be calculated with n += (n / 2) + 1 as n / 2 will evaluate to k.
Another possibility of why your code doesn't get accepted is input/output. You'll have to follow the exact requirements of the platform.
The following bit of the problem description is ignored by your code:
The input will consist of a series of pairs of integers
This can be fixed easily
int main()
{
int max=0,a,b,step;
while ( cin >> a >> b )
{
std::cout << a << ' ' << b << ' ';
if (a >= b)
{
std::cout << max_between(b,a);
}
else
{
std::cout << max_between(a,b);
}
std::cout << std::endl;
}
return 0;
}