If I want to find the total number of odd integers between a leftrange and a rightrange, do you think this works ?
example leftrange = 3, rightrange = 8.
int FindOdd(int left, int right)
{
bool lefteven = (left % 2) ? false: true;
bool righteven = (right % 2) ? false: true;
int length = (right-left) + 1;
if (lefteven != righteven) //even length
{
return (length/2);
}
else //odd length
{
if (!lefteven)
return ((length/2) + 1);
else
return (length/2);
}
}
It's a clumsy way to do it. A better way is to use integer division:
unsigned FindOdd(unsigned a, unsigned b)
{
return b / 2 - a / 2;
}
This will not include the final number if b is odd. I've cheekily changed the types to unsigned for the sake of elegance.
Related
I have a class, call it 'BigNumber', which has a vector v field.
Each element should be one digit.
I want to implement a method to multiply this vector by an integer, but also keep elements one digit.
E.g: <7,6> * 50 = <3,8,0,0>
The vector represents a number, stored in this way. In my example, <7,6> is equal to 76, and <3,8,0,0> is 3800.
I tried the following, but this isn't good (however it works), and not the actual solution for the problem.
//int num, BigNumber bn
if (num > 0)
{
int value = 0, curr = 1;
for (int i = bn.getBigNumber().size() - 1; i >= 0; i--)
{
value += bn.getBigNumber().at(i) * num * curr;
curr *= 10;
}
bn.setBigNumber(value); //this shouldn't be here
return bn;
}
The expected algortithm is multiply the vector itself, not with a variable what I convert to this BigNumber.
The way I set Integer to BigNumber:
void BigNumber::setBigNumber(int num)
{
if (num > 0)
{
bigNum.clear();
while (num != 0)
{
bigNum.push_back(num % 10);
num = (num - (num % 10)) / 10;
}
std::reverse(bigNum.begin(), bigNum.end());
}
else
{
throw TOOSMALL;
}
};
The method I want to implement:
//class BigNumber{private: vector<int> bigNum; ... }
void BigNumber::multiplyBigNumber(BigNumber bn, int num)
{
if (num > 0)
{
//bn.bigNum * num
}
else
{
throw TOOSMALL;
}
}
As this is for a school project, I don't want to just write the code for you. So here's a hint.
Let's say you give me the number 1234 --- and I choose to store each digit in a vector in reverse. So now I've got bignum = [4, 3, 2, 1].
Now you ask me to multiply that by 5. So I create a new, empty vector result=[ ]. I look at the first item in bignum. It's a 4.
4 * 5 is 20, or (as you do at school) it is 0 carry 2. So I push the 0 into result, giving result = [0] and carry = 2.
Questions for you:
If you were doing this by hand (on paper), what would you do next?
Why did I decide to store the digits in reverse order?
Why did I decide to use a new vector (result), rather than modifying bignum?
and only after you have a worked out how to multiply a bignum by an int:
How would you multiply two bignums together?
The solutin for the problem is the follow code. I don't know if I can make this algorithm faster, but it works, so I'm happy with it.
BigNumber BigNumber::multiplyBigNumber(BigNumber bn, int num){
if (num > 0)
{
std::vector<int> result;
std::vector<int> rev = bn.getBigNumber();
std::reverse(rev.begin(),rev.end());
int carry = 0;
for(int i = 0; i<rev.size(); i++){
result.push_back((rev[i] * num + carry) % 10);
carry = (rev[i] * num + carry) / 10;
if(i == rev.size()-1 && carry / 10 == 0 && carry % 10 != 0 ) {
result.push_back(carry);
carry = carry / 10;
}
}
while((carry / 10) != 0){
result.push_back(carry % 10);
carry /= 10;
if(carry / 10 == 0) result.push_back(carry);
}
std::reverse(result.begin(),result.end());
bn.setBigNumber(result);
return bn;
}else{
throw TOOSMALL;
}
}
I need to make a simple function in c++ that will say if an entered integer has its digits ascending from left to right. Ex, 123 is ascending. We just started learning recurssion, which is what I'm supposed to use, but I'm confused. So far what I was thinking is that you store the last digit as a temp, then compare that to the next digit, but how would you manage to do that?
bool ascending(int n) {
int temp = n % 10;
while (n / 10 > 0) {
n = n / 10;
if (temp > n % 10) {
return false;
break;
}
temp = n % 10;
}
}
This is the code I have so far, but I'm definitely messing up. I'm not even using recurrsion.
Here is one way you can go about it.
On every iteration, you check that last 2 digits are in order. And when the number is a single digit, return true
bool ascending(int n) {
int last_digit = n % 10;
int remainder = n / 10;
if (remainder == 0)
{
return true;
}
int second_last_digit = remainder % 10;
if (last_digit < second_last_digit)
{
return false;
}
else
{
return ascending(remainder); // Recusrive call
}
}
I'm trying to implement a primality check function with a deterministic Miller-Rabin algorithm but the results are not always correct: when checking first 1,000,000 numbers it only founds 78,495 instead of 78,498.
This is obtained using [2, 7, 61] as a base which, according to wikipedia, should always be correct for values up to 4,759,123,141.
The interesting thing is that the 3 missing primes are exactly the ones componing the base (2, 7 and 61).
Why is this happening? The code I'm using is the following:
T modular_power(T base, T exponent, T modulo) {
base %= modulo;
T result = 1;
while (exponent > 0) {
if (exponent % 2 == 1)
result = (result * base) % modulo;
base = (base * base) % modulo;
exponent /= 2;
}
return result;
}
bool miller_rabin(const T& n, const vector<T>& witnesses) {
unsigned int s = 0;
T d = n - 1;
while (d % 2 == 0) {
s++;
d /= 2;
}
for (const auto& a : witnesses) {
if (modular_power<T>(a, d, n) == 1)
continue;
bool composite = true;
for (unsigned int r = 0; r < s; r++) {
if (modular_power<T>(a, (T) pow(2, r) * d, n) == n - 1) {
composite = false;
break;
}
}
if (composite)
return false;
}
return true;
}
bool is_prime(const T& n) {
if (n < 4759123141)
return miller_rabin(n, {2, 7, 61});
return false; // will use different base
}
Miller-Rabin indeed does not work when the base and the input are the same. What happens in that case is that ad mod n is zero (because a mod n is zero, so this is really raising zero to some irrelevant power), and the rest of the algorithm is unable to "escape" from zero and concludes that you're dealing with a composite.
As a special case of that, Miller-Rabin never works with an input of 2, because there is no base that can be selected. 2 itself is useless, so is 1, that leaves nothing.
i'm trying to do a subtraction of digits in a recursive way, lets say that I have the number 125 then the subtraction takes place doing it this way
5-2-1 = 2
I've already done the sum with recursion but i'm stuck thinking about it because i'm trying to get each digit and then subtract it within the function itself this way
int RecursiveMath::restaDigitos(int n){
if(n/10 <= 1){
return 0;
}else{
return restaDigitos(n/10) - n%10;
}
}
I do know this function is not working but it's what i've tried along with many combinations, I feel like i'm complicating it too much, any help/advice would be highly appreciated!
You can simplify the task because 5 - 2 - 1 is equal to 5 - (2 + 1), so we can sum up all digits except highest, and subtract this sum from it.
int subtractDigits(const unsigned int n, const bool first = true){
if(n == 0){
return 0;
}
if(first){
return n % 10 - subtractDigits(n / 10, false);
}
else{
return n % 10 + subtractDigits(n / 10, false);
}
}
AHHH This one was tricky
#include <stdio.h>
int restaDigitos(int n){
printf("Processing: %d\n", n);
printf("division: %d\n", n/10);
if(n==0){
return 0;
}else{
return n%10 + restaDigitos(n/10);
}
}
int main() {
int input = 125;
int firstVal = input % 10;
int result = restaDigitos(input / 10);
printf("result: %d\n", firstVal - result);
}
Two major corrections were made:
Your termination condition was neglecting the last case where a single digit remains so it terminated early
The first value cannot be recursive because it is positive. (5-2-1) -> The first number 5 is positive whereas the other values are negative
Hope this helped!
The problem is that you are also subtracting the last number (0 - 1 -2 - 5), but from what I can tell from your question, you want to add it (0 - 1 -2 + 5). My solution is to add another argument specifying the number of digits so that you know when to add instead of subtract
int RecursiveMath::restaDigitos(int n, int numDigits){
if (n == 0) {
return 0;
} else if (n / (pow(10, numDigits - 1)) >= 1){
return restaDigitos(n/10, numDigits) + n % 10;
} else {
return restaDigitos(n / 10, numDigits) - n % 10;
}
}
You are processing the first value differently that the others. Such a use case leads to tricky recursion ways, using default parameters or static values for one shot solutions.
Here you could use:
int restaDigitos(int val, bool first = true, int curr = 0) {
if (val == 0) return curr;
if (first) curr = val%10;
else curr -= val%10;
return restaDigitos(val/10, false, curr);
}
You can control that restaDigitos(125); gives as expected 2.
I was just writing an improved linear version of a recursive Fibonacci algorithm, and realized that my boolean expressions look really bad and unreadable. Is there a cleaner way to do what I'm trying to do?
int fibonacci(int num) {
if (num <= 1)
return num;
// starts looking ugly here
int a = intExists(num-1);
int b = intExists(num-2);
bool aAndB = (a != -1 && b != -1);
bool justA = (a != -1 && b == -1);
bool justB = (a == -1 && b != -1);
int number = 0;
if (aAndB)
number = (a + b);
else if (justA)
number = (a + fibonacci(num - 2));
else if (justB)
number = (fibonacci(num-1) + b);
else
number = (fibonacci(num - 1) + fibonacci(num - 2));
map.push_back(Pair(num, number));
return number;
}
Thanks
If you're talking about:
bool aAndB = (a != -1 && b != -1);
then I would say, "no."
This code looks perfectly expressive to me. aAndB is initialized at the moment it comes in to being, and the conditions are very clear. This might look a bit odd when you're first starting out in C++, but before you know it it will be second nature and other constructs will seem silly.
One thing I would suggest is to make aAndB const if you don't intend to change it:
const bool aAndB = (a != -1 && b != -1);
This is even more expressive.
It also might give the compiler an additional opportunity to optimize your code.
Remember -- write code for humans to understand. Not for computers to understand.
Why don't you make a and b as bools and assign those as true if a == -1 and false otherwise. Then, the expressions will become easier to handle.
Could do a switch statement to clean up the if else statements a little. Other than that just add comments
You could rewrite it to use conditional branching, like this:
int fibonacci(int num) {
if (num <= 1)
return num;
int a = intExists(num-1);
int b = intExists(num-2);
const bool isA = (a != -1); // change in the definition
const bool isB = (b != -1); // change in the definition
int number = 0;
if (isA && isB)
number = (a + b);
else if (isA) // conditionnal branching
number = (a + fibonacci(num - 2));
else if (isB) // conditionnal branching
number = (fibonacci(num-1) + b);
else
number = (fibonacci(num - 1) + fibonacci(num - 2));
map.push_back(Pair(num, number));
return number;
}
I'm assuming that intExists(n) looks up map and if finds n in there, returns fibonacci(n) else it returns -1. Then you could do this:
int fibonacci(int num) {
if (num <= 1)
return num;
int a = intExists(num-1);
int b = intExists(num-2);
if (a == -1) // if a wasn't found, then compute it
a = fibonacci(num-1);
if (b == -1) // if b wasn't found, then compute it
b = fibonacci(num-2);
int number = a + b;
map.push_back(std::make_pair(num, number));
return number;
}
Bonus:
Here is another completely different implementation of fibonnacci() based on Binet's formula:
#include <cmath>
int fibonacci(int n) {
static const double e1 = 1.6180339887498948482045868343656; // = (1 + sqrt(5)) / 2
static const double e2 = -0.61803398874989484820458683436564; // = (1 - sqrt(5)) / 2
static const double c = 0.44721359549995793928183473374626; // = 1 / sqrt(5);
double f = c * (std::pow(e1, n) - std::pow(e2, n));
return static_cast<int>(f + 0.5);
}
int main() {
for (int n = 1; n < 15; ++n)
std::cout << fibonacci(n) << ' ';
}
It outputs:
1 1 2 3 5 8 13 21 34 55 89 144 233 377
Plain C++ code is clean enough:
bool a = intExists(num-1);
bool b = intExists(num-2);
if (a && b) {
//
} else if (a) {
//
} else if (b) {
//
} else {
//
}
int a = intExists(num-1);
int b = intExists(num-2);
bool aAndB = (a != -1 && b != -1);
bool justA = (a != -1 && b == -1);
bool justB = (a == -1 && b != -1);
Quick look into the approach you took. Under what circumstances can justB be true? (Hint: never)
That should help you simplify your approach, although there are better approaches than memoization.
Changing intExists to return boolean values, you can do a switch-case statements like that:
bool a = intExists(num-1);
bool b = intExists(num-2);
switch ((a << 1) + b) {
default: // none exists
case 1: // only b exist
case 2: // only a exist
case 3: // both exists
}
The rationale is to transform those booleans in a binary number
A slightly drastic rewrite is to let an external function handle the lookup table.
That way you don't need to care about more than one value at a time.
This one uses map so I didn't have to write so much in order to test it, but it should be easy enough to adapt:
std::map<int, int> table;
int fibonacci(int num);
int value(int num)
{
int result = table[num];
if (!result)
{
result = fibonacci(num);
table[num] = result;
}
return result;
}
int fibonacci(int num)
{
if (num <= 2)
return 1;
return value(num - 1) + value(num - 2);
}