How to toggle a variable in a loop - c++

Variable i toggles between 2 and 3 and multiplied into a, as in the following example:
a=2;
a=a*i // a=2*2=4 i=2
a=a*i // a=4*3=12 i=3
a=a*i // a=12*2=24 i=2
a=a*i // a=24*3=72 i=3
which goes on as long as a is < 1000.
How can I give the i two values sequentially as shown in the example?

int a = 2, i = 2;
while( a < 1000 )
{
a *= i;
i = 5 - i;
}
and many other ways.

You should be able to use a loop
int a = 2;
bool flip = true;
while (a < 1000)
{
a *= flip ? 2 : 3;
flip = !flip;
}

You can't have i be equal to two values at the same time. You can however make i alternate between 2 and 3 until a < 1000. Below is the code;
int a = 2;
int counter = 0;
while (a < 1000) {
if (counter % 2 == 0) {
a *= 2;
}
else {
a *= 3;
}
counter++;
}

Here's a quick solution that doesn't involve a conditional.
int c = 0;
while (a < 1000)
a *= (c++ % 2) + 2;
or even
for(int c = 0; a < 1000; c++)
a *= (c % 2) + 2;
The modulo is found, which results in either a 0 or a 1 and then shifted up by 2 resulting in either 2 or 3.
Here's another efficient way to do this.
#include <iostream>
using namespace std;
int main() {
int its_bacon_time;
int i = ++(its_bacon_time = 0);
int y = 18;
int z = 9;
bool flag = !false;
int sizzle;
typedef bool decision_property;
#define perhaps (decision_property)(-42*42*-42)
#ifdef perhaps
# define YUM -
# define YUMMM return
#endif
bool bacon = !(bool) YUM(sizzle = 6);
if(flag)
std::cout << "YEP" << std::endl;
while (flag) {
if (bacon = !bacon)
flag = !flag; // YUM()?
if (YUM((YUM-i)YUM(i*2))+1>=((0x1337|0xECC8)&0x3E8))
(*((int*)&flag)) &= 0x8000;
else
flag = perhaps;
std::cout << i << " ";
int multiplicative_factor = y / (bacon ? z : y);
int* temporal_value_indicator = &i;
(**(&temporal_value_indicator)) *=
(((((multiplicative_factor & 0x0001) > 0) ? sizzle : bacon) // ~yum~
<< 1) ^ (bacon? 0 : 15));
std::cout << (((((multiplicative_factor & 0x0001) > 0) ? sizzle : bacon) // ~yum~
<< 1) ^ (bacon? 0 : 15)) << std::endl;
}
YUMMM its_bacon_time;
}
Point is that you should probably try something yourself first before asking for something that is really simple to achieve.

int main()
{
int a = 2;
int multiplier;
for (int i = 0; a < 1000; ++i)
{
multiplier = (i % 2) ? 2 : 3;
a *= multiplier;
}
}

Related

How can I get the common digits of two int in C++? Example: (1234, 41567) --> 1 4

Given two int I want to get all the common digits and print out them separated by spaces.
So for example, if int x=1234; int y=41567; then I want to print out: 1 4.
This is my code. It does not work properly. When I run it, it prints 0 1 2 3 4 5 then stops.
I don't want to use vector nor arrays.
void problema3() {
int x, y, kX=0, kY=0;
cout << "x="; cin >> x;
cout << "y="; cin >> y;
int cx = x;
int cy = y;
for (int i = 0; i < 10; i++) {
kX = 0;
kY = 0;
x = cx;
y = cx;
while (x != 0 || kX==0) {
if (x % 10 == i) kX=1;
x /= 10;
}
while (y != 0 || kY == 0) {
if (y % 10 == i) kY=1;
y /= 10;
}
if (kX == 1 && kY == 1) cout << i << ' ';
}
}
int main()
{
problema3();
return 0;
}
If you're allowed to use std::set then you can do what you want as follows:
#include <iostream>
#include <set>
void print(int x, int y)
{
int individual_number1 = 0, individual_number2 = 0;
std::set<int> myset;
int savey = y;//this will be used to reset y when the 2nd do while loop finishes
do
{
individual_number1 = x % 10;
do
{
individual_number2 = y % 10;
if(individual_number1 == individual_number2)
{
myset.insert(individual_number1);
break;
}
y = y / 10;
}while( y > 0);
y = savey;
x = x / 10;
} while (x > 0);
//print out the element of the set
for(int i: myset)
{
std::cout<<i<<" ";
}
}
int main()
{
int x = 1234, y = 41567;
print(x, y);
return 0;
}
The output of the above program is as follows:
1 4
which can be seen here.
Your main bug is when assigning copies of cy.
//...
for (int i = 0; i < 10; i++) {
//...
x = cx;
y = cx; // <-- BUG! should read y = cy;
But that's not the only bug in your program.
Your digit detection logic is wrong. In particular, zero is not handled correctly, and since you did not put that reusable code in a function, your program is way more complex than it needs.
Here's the corrected logic for digit detection.
// checks if base 10 representation of a positive integer contains a certain digit (0-9)
bool hasDigit(int x, int d)
{
do
{
if (x % 10 == d)
return true;
x /= 10;
} while (x != 0);
return false;
}
Your main loop then becomes:
// assuming int x, y as inputs.
// ...
for (int i = 0; i < 10; ++i)
{
if (hasDigit(x, i) && hasDigit(y, i))
std::cout << i << ' ';
}
Which leaves very little room for bugs.
You can play with the code here: https://godbolt.org/z/5c5brEcEq

Adding negative and positive numbers up to 10^100000

I've been trying to solve this problem (from school) for just about a week now. We're given two numbers, from -(10^100000) to +that.
Of course the simplest solution is to implement written addition, so that's what I did. I decided, that I would store the numbers as strings, using two functions:
int ti(char a) { // changes char to int
int output = a - 48;
return output;
}
char tc(int a) { // changes int to char
char output = a + 48;
return output;
}
This way I can store negative digits, like -2. With that in mind I implemented a toMinus function:
void toMinus(std::string &a) { // 123 -> -1 -2 -3
for (auto &x : a) {
x = tc(-ti(x));
}
}
I also created a changeSize function, which adds 0 to the beginning of the number until they are both their max size + 1 and removeZeros, which removes leading zeros:
void changeSize(std::string &a, std::string &b) {
size_t exp_size = std::max(a.size(), b.size()) + 2;
while (a.size() != exp_size) {
a = '0' + a;
}
while (b.size() != exp_size) {
b = '0' + b;
}
}
void removeZeros(std::string &a) {
int i = 0;
for (; i < a.size(); i++) {
if (a[i] != '0') {
break;
}
}
a.erase(0, i);
if (a.size() == 0) {
a = "0";
}
}
After all that, I created the main add() function:
std::string add(std::string &a, std::string &b) {
bool neg[2] = {false, false};
bool out_negative = false;
if (a[0] == '-') {
neg[0] = true;
a.erase(0, 1);
}
if (b[0] == '-') {
neg[1] = true;
b.erase(0, 1);
}
changeSize(a, b);
if (neg[0] && !(neg[1] && neg[0])) {
toMinus(a);
}
if(neg[1] && !(neg[1] && neg[0])) {
toMinus(b);
}
if (neg[1] && neg[0]) {
out_negative = true;
}
// Addition
for (int i = a.size() - 1; i > 0; i--) {
int _a = ti(a[i]);
int _b = ti(b[i]);
int out = _a + _b;
if (out >= 10) {
a[i - 1] += out / 10;
} else if (out < 0) {
if (abs(out) < 10) {
a[i - 1]--;
} else {
a[i - 1] += abs(out) / 10;
}
if (i != 1)
out += 10;
}
a[i] = tc(abs(out % 10));
}
if (ti(a[0]) == -1) { // Overflow
out_negative = true;
a[0] = '0';
a[1]--;
for (int i = 2; i < a.size(); i++) {
if (i == a.size() - 1) {
a[i] = tc(10 - ti(a[i]));
} else {
a[i] = tc(9 - ti(a[i]));
}
}
}
if (neg[0] && neg[1]) {
out_negative = true;
}
removeZeros(a);
if (out_negative) {
a = '-' + a;
}
return a;
}
This program works in most cases, although our school checker found that it doesn't - like instead of
-4400547114413430129608370706728634555709161366260921095898099024156859909714382493551072616612065064
it returned
-4400547114413430129608370706728634555709161366260921095698099024156859909714382493551072616612065064
I can't find what the problem is. Please help and thank you in advance.
Full code on pastebin
While I think your overall approach is totally reasonable for this problem, your implementation seems a bit too complicated. Trying to solve this myself, I came up with this:
#include <iostream>
#include <limits>
#include <random>
#include <string>
bool greater(const std::string& a, const std::string& b)
{
if (a.length() == b.length()) return a > b;
return a.length() > b.length();
}
std::string add(std::string a, std::string b)
{
std::string out;
bool aNeg = a[0] == '-';
if (aNeg) a.erase(0, 1);
bool bNeg = b[0] == '-';
if (bNeg) b.erase(0, 1);
bool resNeg = aNeg && bNeg;
if (aNeg ^ bNeg && (aNeg && greater(a, b) || bNeg && greater(b, a)))
{
resNeg = true;
std::swap(a, b);
}
int i = a.length() - 1;
int j = b.length() - 1;
int carry = 0;
while (i >= 0 || j >= 0)
{
const int digitA = (i >= 0) ? a[i] - '0' : 0;
const int digitB = (j >= 0) ? b[j] - '0' : 0;
const int sum = (aNeg == bNeg ? digitA + digitB : (bNeg ? digitA - digitB : digitB - digitA)) + carry;
carry = 0;
if (sum >= 10) carry = 1;
else if (sum < 0) carry = -1;
out = std::to_string((sum + 20) % 10) + out;
i--;
j--;
}
if (carry) out = '1' + out;
while (out[0] == '0') out.erase(0, 1);
if (resNeg) out = '-' + out;
return out;
}
void test()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(-std::numeric_limits<int32_t>::max(), std::numeric_limits<int32_t>::max());
for (int i = 0; i < 1000000; ++i)
{
const int64_t a = dis(gen);
const int64_t b = dis(gen);
const auto expected = std::to_string(a + b);
const auto actual = add(std::to_string(a), std::to_string(b));
if (actual != expected) {
std::cout << "mismatch expected: " << expected << std::endl;
std::cout << "mismatch actual : " << actual << std::endl;
std::cout << " a: " << a << std::endl;
std::cout << " b: " << b << std::endl;
}
}
}
int main()
{
test();
}
It can potentially be further optimized, but the main points are:
If the sign of both numbers is the same, we can do simple written addition. If both are negative, we simply prepend - at the end.
If the signs are different, we do written subtraction. If the minuend is greater than the subtrahend, there's no issue, we know that the result will be positive. If, however, the subtrahend is greater, we have to reformulate the problem. For example, 123 - 234 we would formulate as -(234 - 123). The inner part we can solve using regular written subtraction, after which we prepend -.
I test this with random numbers for which we can calculate the correct result using regular integer arithmetic. Since it doesn't fail for those, I'm pretty confident it also works correctly for larger inputs. An approach like this could also help you uncover cases where your implementation fails.
Other than that, I think you should use a known failing case with a debugger or simply print statements for the intermediate steps to see where it fails. The only small differences in the failing example you posted could point at some issue with handling a carry-over.

How to perform BigInteger multiplication on char vectors?

I'm implementing a BigInt in c++ and am trying to overload the multiplication operator. I'm storing large integers in a char vector.
vector<char> storage;
Here is what I did to implement operator*(int)
BigInt BigInt::operator*(int x)
{
int extra = 0;
int dec_mod = pow(10, this->storage.size());
for (auto & g : storage) {
g = g * x + extra;
int mod_g = g % dec_mod;
extra = g / dec_mod;
g = mod_g;
}
while (extra > 0) {
storage.push_back(extra % dec_mod);
extra /= dec_mod;
}
return *this;
}
The operator*(bigInt) function returns wrong answers. For example, 33 * 4 returns 1212 and not 132.This was my attempt at writing the overloaded operator* which takes a bigint object:
BigInt BigInt::operator*(BigInt bigN) {
int carry = 0;
for (int i = bigN.storage.size()-1; i >= 0; i--) {
for (int j = this->storage.size()-1; j >= 0; j--) {
int val = (this->storage.at(i) * bigN.storage.at(j)) + carry;
this->storage.push_back(val % 10);
carry = val / 10;
}
}
return *this;
}
It looks like the logic in the carry is flawed, but i'm not sure how to fix it.
I'm not sure how you're trying to do this, but here is a walkthrough of why you're getting the result 1212 instead of 132:
BigInt operator*(int x)// x is 4
{
// Let's say storage holds 33, that's
// {3, 3} in your char vector;
int extra = 0;
int dec_mod = pow(10, this->storage.size()); // dec_mod may be 100
for (auto & g : storage)
{
g = g * x + extra; // same as g = 3 * 4 + 0, g = 12
int mod_g = g % dec_mod; // same as mod_g = 12 % 100 = 12
extra = g / dec_mod; // same as 12 / 100 = 0
g = mod_g; // g = 12
}
// Exact same thing happens on the second iteration, your storage vector
// ends up as {12, 12};
// That's why your result is 1212
while (extra > 0) {
storage.push_back(extra % dec_mod);
extra /= dec_mod;
}
return *this;
}
I'm not sure how you are trying to do it, but here's my attempt, it's just as one would do it on paper:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct BigInt
{
BigInt(std::string num) { for (auto &i : num) storage.push_back(i - 48); }
BigInt(std::vector<char> numVect) : storage(numVect) {}
vector<char> storage;
string getAsString()
{ string str; for (auto& i : storage) str += i + 48; return str; }
// Add 48 to turn 0 - 9 to ascii string.
vector<char> add(vector<char>& lhs, vector<char>& rhs)
// Add function only needed if number is multiplied by more than one digit.
{
// Fill with zeros to make both vectors same length.
int sizeDiff = (int)lhs.size() - (int)rhs.size();
if (sizeDiff < 0)
lhs.insert(lhs.begin(), abs(sizeDiff), 0);
else if (sizeDiff > 0)
rhs.insert(rhs.begin(), abs(sizeDiff), 0);
vector<char> resultVect;
int carry = 0;
for (int i = lhs.size() - 1; i >= 0; --i)
{
int result = lhs[i] + rhs[i] + carry;
carry = result / 10;
result %= 10;
resultVect.insert(resultVect.begin(), result);
}
if (carry != 0) resultVect.insert(resultVect.begin(), carry);
return resultVect;
}
BigInt operator*(BigInt rhs)
{
int unitPlace = 0; // Keeps track of how many zeros to add in subsequent results
vector<char> totalVect; // Accumulated value after each addition
vector<char> resultVect; // Result of this particular multiplication
for (int i = rhs.storage.size() - 1; i >= 0; --i, unitPlace++)
{
int carry = 0;
for (int k = 0; k < unitPlace; ++k) resultVect.push_back(0);
for (int j = storage.size() - 1; j >= 0; j--)
{
int result = rhs.storage[i] * storage[j] + carry;
carry = result / 10;
result %= 10;
resultVect.insert(resultVect.begin(), result);
}
resultVect.insert(resultVect.begin(), carry);
totalVect = add(totalVect, resultVect); // Add sub-result
resultVect.clear();
}
// Strip leading zeros
for (int i = 0; i < totalVect.size(); ++i) {
if (totalVect[i] == 0) totalVect.erase(totalVect.begin() + i);
else break;
}
return BigInt{ totalVect };
}
};
int main()
{
BigInt a{ "335467" };
BigInt b{ "1019737" };
BigInt c = a * b;
std::cout << c.getAsString() << '\n';
cin.ignore();
return 0;
}

How to I reduce a chain of if statements?

How to I reduce a chain of if statements in C++?
if(x == 3) {
a = 9876543;
}
if(x == 4) {
a = 987654;
}
if(x == 5) {
a = 98765;
}
if(x == 6) {
a = 9876;
}
if(x == 7) {
a = 987;
}
if(x == 8) {
a = 98;
}
if(x == 9) {
a = 9;
}
This is the example code.
You can generate this value mathematically, by using integer division:
long long orig = 9876543000;
long long a = orig / ((long) pow (10, x));
EDIT:
As #LogicStuff noted in the comments, it would be much more elegant to subtract 3 from x, instead of just multiplying orig by another 1000:
long orig = 9876543;
long a = orig / ((long) pow (10, x - 3));
With an array, you may do:
if (3 <= x && x <= 9) {
const int v[] = {9876543, 987654, 98765, 9876, 987, 98, 9};
a = v[x - 3];
}
Something like:
#include <iostream>
#include <string>
int main() {
int x = 4;
int a = 0;
std::string total;
for(int i = 9; i > 0 ; --i)
{
if(x <= i)
total += std::to_string(i);
}
a = std::stoi(total, nullptr);
std::cout << a << std::endl;
return 0;
}
http://ideone.com/2Cdve1
If the data can be derived, I'd recommend using one of the other answers.
If you realize their are some edge cases that end up making the derivation more complicated, consider a simple look-up table.
#include <iostream>
#include <unordered_map>
static const std::unordered_multimap<int,int> TABLE
{{3,9876543}
,{4,987654}
,{5,98765}
,{6,9876}
,{7,987}
,{8,98}
,{9,9}};
int XtoA(int x){
int a{0};
auto found = TABLE.find(x);
if (found != TABLE.end()){
a = found->second;
}
return a;
}
int main(){
std::cout << XtoA(6) << '\n'; //prints: 9876
}

Laguerre interpolation algorithm, something's wrong with my implementation

This is a problem I have been struggling for a week, coming back just to give up after wasted hours...
I am supposed to find coefficents for the following Laguerre polynomial:
P0(x) = 1
P1(x) = 1 - x
Pn(x) = ((2n - 1 - x) / n) * P(n-1) - ((n - 1) / n) * P(n-2)
I believe there is an error in my implementation, because for some reason the coefficents I get seem way too big. This is the output this program generates:
a1 = -190.234
a2 = -295.833
a3 = 378.283
a4 = -939.537
a5 = 774.861
a6 = -400.612
Description of code (given below):
If you scroll the code down a little to the part where I declare array, you'll find given x's and y's.
The function polynomial just fills an array with values of said polynomial for certain x. It's a recursive function. I believe it works well, because I have checked the output values.
The gauss function finds coefficents by performing Gaussian elimination on output array. I think this is where the problems begin. I am wondering, if there's a mistake in this code or perhaps my method of veryfying results is bad? I am trying to verify them like that:
-190.234 * 1.5 ^ 5 - 295.833 * 1.5 ^ 4 ... - 400.612 = -3017,817625 =/= 2
Code:
#include "stdafx.h"
#include <conio.h>
#include <iostream>
#include <iomanip>
#include <math.h>
using namespace std;
double polynomial(int i, int j, double **tab)
{
double n = i;
double **array = tab;
double x = array[j][0];
if (i == 0) {
return 1;
} else if (i == 1) {
return 1 - x;
} else {
double minusone = polynomial(i - 1, j, array);
double minustwo = polynomial(i - 2, j, array);
double result = (((2.0 * n) - 1 - x) / n) * minusone - ((n - 1.0) / n) * minustwo;
return result;
}
}
int gauss(int n, double tab[6][7], double results[7])
{
double multiplier, divider;
for (int m = 0; m <= n; m++)
{
for (int i = m + 1; i <= n; i++)
{
multiplier = tab[i][m];
divider = tab[m][m];
if (divider == 0) {
return 1;
}
for (int j = m; j <= n; j++)
{
if (i == n) {
break;
}
tab[i][j] = (tab[m][j] * multiplier / divider) - tab[i][j];
}
for (int j = m; j <= n; j++) {
tab[i - 1][j] = tab[i - 1][j] / divider;
}
}
}
double s = 0;
results[n - 1] = tab[n - 1][n];
int y = 0;
for (int i = n-2; i >= 0; i--)
{
s = 0;
y++;
for (int x = 0; x < n; x++)
{
s = s + (tab[i][n - 1 - x] * results[n-(x + 1)]);
if (y == x + 1) {
break;
}
}
results[i] = tab[i][n] - s;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int num;
double **array;
array = new double*[5];
for (int i = 0; i <= 5; i++)
{
array[i] = new double[2];
}
//i 0 1 2 3 4 5
array[0][0] = 1.5; //xi 1.5 2 2.5 3.5 3.8 4.1
array[0][1] = 2; //yi 2 5 -1 0.5 3 7
array[1][0] = 2;
array[1][1] = 5;
array[2][0] = 2.5;
array[2][1] = -1;
array[3][0] = 3.5;
array[3][1] = 0.5;
array[4][0] = 3.8;
array[4][1] = 3;
array[5][0] = 4.1;
array[5][1] = 7;
double W[6][7]; //n + 1
for (int i = 0; i <= 5; i++)
{
for (int j = 0; j <= 5; j++)
{
W[i][j] = polynomial(j, i, array);
}
W[i][6] = array[i][1];
}
for (int i = 0; i <= 5; i++)
{
for (int j = 0; j <= 6; j++)
{
cout << W[i][j] << "\t";
}
cout << endl;
}
double results[6];
gauss(6, W, results);
for (int i = 0; i < 6; i++) {
cout << "a" << i + 1 << " = " << results[i] << endl;
}
_getch();
return 0;
}
I believe your interpretation of the recursive polynomial generation either needs revising or is a bit too clever for me.
given P[0][5] = {1,0,0,0,0,...}; P[1][5]={1,-1,0,0,0,...};
then P[2] is a*P[0] + convolution(P[1], { c, d });
where a = -((n - 1) / n)
c = (2n - 1)/n and d= - 1/n
This can be generalized: P[n] == a*P[n-2] + conv(P[n-1], { c,d });
In every step there is involved a polynomial multiplication with (c + d*x), which increases the degree by one (just by one...) and adding to P[n-1] multiplied with a scalar a.
Then most likely the interpolation factor x is in range [0..1].
(convolution means, that you should implement polynomial multiplication, which luckily is easy...)
[a,b,c,d]
* [e,f]
------------------
af,bf,cf,df +
ae,be,ce,de, 0 +
--------------------------
(= coefficients of the final polynomial)
The definition of P1(x) = x - 1 is not implemented as stated. You have 1 - x in the computation.
I did not look any further.