I wanted to practice math in c++ and I tried making a program that answered this question from math class
0 < r < 1, find the number of rational r values for which the
numerator and the denominator add to make 1000 where r is in simplest
form
After an hour or two debugging, I finally got something that makes it through all the numbers. In class, the answer was 200. I got 216. Run for yourself
#include <math.h>
#include <iostream>
bool rprime_test(int a, int b) {
int tmp = 2;
std::cout << a << "/" << b;
tmp1:
for (tmp; (tmp < a) && (a % tmp != 0); tmp++) {
}
if ((b % tmp == 0 && a % tmp == 0) || b % a == 0) {
std::cout << " == irreduced\n";
return false;
} else if (!tmp < a) {
std::cout << " == reduced\n";
return true;
} else {
//std::cout << tmp << ","<< a << std::endl;
goto tmp1;
}
}
int main() {
int r = 0, a = 1;
int b = 1000 - a;
while (a < b) {
if (rprime_test(a, b)) {
r++;
}
std::cout << "total = " << r << std::endl;
a++;
b = 1000 - a;
//std::cout << "assigned " << a << "/" << b << std::endl;
}
std::cout << "final result = " << r << std::endl;
return 0;
}
please I don't know what I did wrong for this. Also, is there any better way to optimize this?
Your main issue is with your rprime_test function. Without digging too much into your existing function, try using the gcd. Two numbers a and b are an irreducible fraction when they are "coprime," which is when their "greatest common denominator" (gcd) is 1. The way you compute the gcd of two values is with the Euclidean Algorithm:
int gcd (int a, int b) {
return b % a == 0 ? a : gcd (b % a, a);
}
And your check becomes
if (gcd (a, b) == 1) {
a++;
/* etc */
}
Following works:
#include <iostream>
int gcd(unsigned int a, unsigned int b)
{
if (b < a) {
return gcd(b, a);
}
int r = a % b;
while (r != 0) {
a = b;
b = r;
r = a % b;
}
return b;
}
int main()
{
int count = 0;
for (int i = 1; i != 500; ++i) {
if (gcd(1000 - i, i) == 1) {
++count;
}
}
std::cout << count << std::endl;
}
Live example
Related
#include <iostream>
void isMax(int a, int b, int c, int d) {
int ans1, ans0, x;
a = !b, a = !c, a = !d,
b = !c, b = !d,
c = !d, c = !a;
if (a<b && b>c) { // ans0 starts
if (b > d) {
std::cout << b << std::endl;
}
else {
std::cout << d << std::endl;
}
}
else if (a < b && b < c) {
if (c > d) {
std::cout << c << std::endl;
}
else {
std::cout << d << std::endl;
}
}
//ans1
else if (a > b&& a > c) {
if (a > c&& a > d) {
std::cout << a << std::endl;
}
else if (a > c&& a < d) {
std::cout << d << std::endl;
}
else if (a<c && c>d) {
std::cout << c << std::endl;
}
else if (a < c && c < d) {
std::cout << d << std::endl;
}
else {
std::cout << "invalid numbers ahead." << std::endl;
}
}
std::cout << a << b << c << d << std::endl;
};
int main() {
isMax(3, 4, 6, 5);
return 0;
}
it kind of worked before i added
a = !b, a = !c, a = !d,
b = !c, b = !d,
c = !d, c = !a;
this part but did not work when i give the same values for a,b,c,d that`s why i added that part and now it does not work at all.
What is my mistake here ?
This image shows what i am trying to turn into code. Basically i`m trying to write a function that prints out the largest of four variables.
a != b; is true when a and b are different. What you wrote is a = !b; which is "assign to a the logically negated value of b".
I do not see how such assignment could make any sense here. That's why you get correct results without it and non-sense results when you add that assignments.
PS: Even if you "fix" it by writing a != b; the statement alone will have no effect. I suppose you want to return early or skip some of the later conditions when some input is equal.
From your schema, it should be:
void DisplayMax(int a, int b, int c, int d) {
if (b < a) {
if (c < a) {
if (d < a) {
std::cout << a;
} else { // a <= d
std::cout << d;
}
} else { // b < a <= c
if (c < d) {
std::cout << d;
} else {
std::cout << c;
}
}
} else { // a <= b
if (c < b) {
if (d < b) {
std::cout << b;
} else { // b <= d
std::cout << d;
}
} else { // a <= b <= c
if (c < d) {
std::cout << d;
} else {
std::cout << c;
}
}
}
}
But, as shown in other answer, there is simpler ways.
or with std:
void DisplayMax(int a, int b, int c, int d) {
std::cout << std::max({a, b, c, d});
}
I see a few issues:
Your logic seem over complicated for printing the largest of 4 variables.
The name of the isMax function doesn't reflect what it does.
I don't understand the need for a "invalid numbers ahead" if indeed printing the largest of four integers is intended.
I propose a simpler logic with fewer conditions but another variable on the heap.
#include <iostream>
int largestOf(int a, int b, int c, int d) {
int max = a;
if (b > max)
max = b;
if (c > max)
max = c;
if (d > max)
max = d;
return max;
}
void isMax(int a, int b, int c, int d) {
std::cout << largestOf(a, b, c, d) << std::endl;
}
It's not clear at all what you expect the a = !b, ... to accomplish, so I'm going to ignore that.
I am also going to ignore the existence of std::max since this is clearly an exercise.
Your logic tree makes sense, but you can find a more convenient solution if you bark up a different but similar tree.
Consider the case when a > b, i.e. you know for certain that b is not the maximum.
Instead of continuing with a, now look at only c and d.
If c > d, you know that the maximum is not d, so it must be either a or c.
Likewise, if d > c, the maximum is either a or d.
The same line of reasoning for the case when b > a leads to the following algorithm:
Determine max(a,b).
Determine max(c,d).
The maximum of all four numbers is the maximum of the previous two results.
In code:
void isMax(int a, int b, int c, int d) {
int ans0 = a > b ? a : b;
int ans1 = c > d ? c : d;
std::cout << (ans0 > ans1 ? ans0 : ans1) << std::endl;
}
On a side note, a function whose name begins with "is" usually returns a boolean, and you will find more use for a function that returns the maximum than you will of one that prints it.
You can always print that value later if you want to look at it.
Like this:
int max(int a, int b, int c, int d) {
int ans0 = a > b ? a : b;
int ans1 = c > d ? c : d;
return ans0 > ans1 ? ans0 : ans1;
}
This code is over complicated for something fairly simple. If you're new to programming, I suggest you try using arrays, in that way you can easily decide which number is max.
For example:
void isMax(int a, int b, int c, int d) {
int j[4] = { a,b,c,d };
int max = j[0];
for (int i = 1; i < 4; i++) {
if (j[i] > max){ max = j[i]; }
}
cout << max;
}
This is a better way to do it.
So far I have this code. I'm trying to print prime factorization with exponents. For example, if my input is 20, the output should be 2^2, 5
#include <iostream>
#include <cmath>
using namespace std;
void get_divisors (int n);
bool prime( int n);
int main(int argc, char** argv) {
int n = 0 ;
cout << "Enter a number and press Enter: ";
cin >>n;
cout << " Number n is " << n << endl;
get_divisors(n);
cout << endl;
return 0;
}
void get_divisors(int n){
double sqrt_of_n = sqrt(n);
for (int i =2; i <= sqrt_of_n; ++i){
if (prime (i)){
if (n % i == 0){
cout << i << ", ";
get_divisors(n / i);
return;
}
}
}
cout << n;
}
bool prime (int n){
double sqrt_of_n = sqrt (n);
for (int i = 2; i <= sqrt_of_n; ++i){
if ( n % i == 0) return 0;
}
return 1;
}
I hope someone can help me with this.
You can use an std::unordered_map<int, int> to store two numbers (x and n for x^n). Basically, factorize the number normally by looping through prime numbers smaller than the number itself, dividing the number by the each prime as many times as possible, and recording each prime you divide by. Each time you divide by a prime number p, increment the counter at map[p].
I've put together a sample implementation, from some old code I had. It asks for a number and factorizes it, displaying everything in x^n.
#include <iostream>
#include <unordered_map>
#include <cmath>
bool isPrime(const int& x) {
if (x < 3 || x % 2 == 0) {
return x == 2;
} else {
for (int i = 3; i < (int) (std::pow(x, 0.5) + 2); i += 2) {
if (x % i == 0) {
return false;
}
}
return true;
}
}
std::unordered_map<int, int> prime_factorize(const int &x) {
int currentX = abs(x);
if (isPrime(currentX) || currentX < 4) {
return {{currentX, 1}};
}
std::unordered_map<int, int> primeFactors = {};
while (currentX % 2 == 0) {
if (primeFactors.find(2) != primeFactors.end()) {
primeFactors[2]++;
} else {
primeFactors[2] = 1;
}
currentX /= 2;
}
for (int i = 3; i <= currentX; i += 2) {
if (isPrime(i)) {
while (currentX % i == 0) {
if (primeFactors.find(i) != primeFactors.end()) {
primeFactors[i]++;
} else {
primeFactors[i] = 1;
}
currentX /= i;
}
}
}
return primeFactors;
}
int main() {
int x;
std::cout << "Enter a number: ";
std::cin >> x;
auto factors = prime_factorize(x);
std::cout << x << " = ";
for (auto p : factors) {
std::cout << "(" << p.first << " ^ " << p.second << ")";
}
}
Sample output:
Enter a number: 1238
1238 = (619 ^ 1)(2 ^ 1)
To begin with, avoid using namespace std at the top of your program. Second, don't use function declarations when you can put your definitions before the use of those functions (but this may be a matter of preference).
When finding primes, I'd divide the number by 2, then by 3, and so on. I can also try with 4, but I'll never be able to divide by 4 if 2 was a divisor, so non primes are automatically skipped.
This is a possible solution:
#include <iostream>
int main(void)
{
int n = 3 * 5 * 5 * 262417;
bool first = true;
int i = 2;
int count = 0;
while (i > 1) {
if (n % i == 0) {
n /= i;
++count;
}
else {
if (count > 0) {
if (!first)
std::cout << ", ";
std::cout << i;
if (count > 1)
std::cout << "^" << count;
first = false;
count = 0;
}
i++;
if (i * i > n)
i = n;
}
}
std::cout << "\n";
return 0;
}
Note the i * i > n which is an alternative to the sqrt() you are using.
I made a simple recursion program for this question http://www.spoj.com/problems/COINS/, but whenever recursion happens my class variables lose their value and store the value from the recursion loop.
Here's the code:
#include<iostream>
using namespace std;
class a
{
public:
int c = 0, d = 0, b = 0, x = 0;
int recur(int n)
{
b = (n / 2);
if (b >= 12)
{
b = recur(b);
}
c = (n / 3);
if (c >= 12)
{
c = recur(c);
}
d = (n / 4);
if (d >= 12)
{
d = recur(d);
}
x = b + c + d;
return x;
}
};
int main()
{
int n;
while(cin)
{
cin >> n;
int b = 0, r = 0;
a abc;
r = (n > abc.recur(n)) ? (n) : (abc.recur(n));
cout << r << endl;
}
return 0;
}
So for input 12, I'll be getting 13 but for the input value of 44 I'm getting 44.
This could be a working solution:
#include <iostream>
using namespace std;
int changeToDollars(int bytelandians) {
int byTwo = bytelandians / 2;
int byThree = bytelandians / 3;
int byFour = bytelandians / 4;
int sum = byTwo + byThree + byFour;
if (sum < bytelandians) {
return bytelandians;
} else {
return changeToDollars(byTwo) + changeToDollars(byThree) + changeToDollars(byFour);
}
}
int main() {
int bytelandians;
cout << "How much bytelandians?: ";
while (cin >> bytelandians) {
cout << "Corresponding $: " << changeToDollars(bytelandians) << endl;
cout << "How much bytelandians?: ";
}
return 0;
}
The changeToDollars function, using a simple recursive algorithm, exchanges each single Byteland coin into the corresponding three ones with minor value, until the overall converted amount is advantageous.
I have this recursive function that decompose a number in its prime factors, and show the result standard output for example
descompon(2, 10);
Output
2 = 2
3 = 3
4 = 2^2
5 = 5
6 = 2 * 3
7 = 7
8 = 2^3
9 = 3^2
10 = 2 * 5
The code
#include <iostream>
#include <sstream>
int comprobar_primo( int* num, int e )
{
if (*num%e == 0)
{
*num /= e;
return 1 + comprobar_primo(num, e);
}
return 0;
}
std::string factor_primo(int a, int b, std::stringstream& fact)
{
unsigned exp = comprobar_primo(&a, b);
if (exp >= 1)
{
fact << b;
if (exp > 1) fact << '^' << exp;
if (a != 1) fact << " * ";
}
if (a > 1) factor_primo(a, b + 1, fact);
return fact.str();
}
void descompon(int a, int b, int ver)
{
std::stringstream fact;
//std::string result = factor_primo(a, 2, fact);
if(ver)
std::cout << a << " = " << factor_primo(a, 2, fact) << std::endl;
if(a < b)
descompon( a + 1, b, ver);
}
int main(void)
{
descompon(2, 10000, 1);
return 0;
}
The problem is that when reaches the 5922 the program remains frozen, showing:
Process returned -1073741819 <0xC0000005>
why this happens and how I can avoid?
Both your factor_primo and descompon functions can potentially cause stack overflow. Its better to convert them into iterative version. Modified code is given below:
// no need to pass b as argument since we start from b=2 and increment b by 1
std::string factor_primo(int a, std::stringstream& fact)
{
for(int b=2; a>1; b++)
{
if(a%b==0)
{
unsigned exp=comprobar_primo(&a, b);
if(exp >= 1)
{
fact << b;
if(exp > 1) fact << '^' << exp;
if(a != 1) fact << " * ";
}
}
}
return fact.str();
}
void descompon(int a, int b, int ver)
{
if(ver)
{
for(int i=a; i<=b; i++) {
std::stringstream fact;
std::cout << i << " = " << factor_primo(i, fact) << std::endl;
}
}
}
int main(void)
{
descompon(2, 10000, 1);
getchar();
return 0;
}
I am trying to create a program that can take many numbers as I want in C++ language.
Then it find what operators can make the equation true and show all correct possible operation.
Example: If I put 3 5 15
Then it output 3x5 = 15
If I put 1 2 3 4 4
Then it outputs 1+2-3+4 =4
The following code is my written program:
The problem about it is that when I want to reduce the number of input or increase the number of input I need to add/reduce nested loops EVERYTIME. I want to know what is a more effective way of a more flexible nested loops or recursion method.
#include <iostream>
#include <cmath>
using namespace std;
char getOperator(int);
double operate(int, double, double);
int main() {
double a, b, c, d, e, result;
short noOfAnswers = 0;
cout << "Input first 5 numbers to make it equal to another 1 number.\n" <<
"I'll find what are the operators needed to make 2 sides of the equation equal.\n";
cin >> a >> b >> c >> d >> e >> result;
int noOfOperators = 5;
for (int i = 0; i <= noOfOperators; i++) {
double firstTwo = operate(i, a, b);
for (int j = 0; j <= noOfOperators; j++) {
double firstThree = operate(j, firstTwo, c);
for (int k = 0; k <= noOfOperators; k++) {
double firstFour = operate(k, firstThree, d);
for (int l = 0; l <= noOfOperators; l++) {
double firstFive = operate(l, firstFour, e);
if (firstFive == result) {
cout << ++noOfAnswers << ')' << a << getOperator(i) << b << getOperator(j) << c
<< getOperator(k) << d << getOperator(l) << e << '=' << result << endl;
}
}
}
}
}
if (noOfAnswers) cout << "I have found " << noOfAnswers << " solutions for this extremely hard problem for humanity \nin less than a second." << endl;
else cout << "I cannot find any solutions to this problem.\n"
<<"They're just a bunch of random numbers & That is UNSOLVABLE!" << endl;
cout << "Do not doubt my judgment. I am always right!" << endl << "(Please note that all calculations are done from the left side first.)" << endl;
return 0;
}
double operate(int iteration, double num1, double num2) {
switch (iteration) {
case 0: return num1+num2;
case 1: return num1-num2;
case 2: return num1*num2;
case 3: return num1/num2;
case 4: return pow(num1, num2);
case 5: return fmod(num1, num2);
}
return 0;
}
char getOperator(int pos) {
switch (pos) {
case 0: return '+';
case 1: return '-';
case 2: return 'x';
case 3: return '/';
case 4: return '^';
case 5: return '%';
}
return ' ';
}
You might want to use while() loops, cause you dont know when the loop terminates.
int main() {
double numbers[] = {3,5,15};//consider storing the number as an array
//the last element is the result
double result;
int arr_len = sizeof(numbers)/sizeof(double);
int i,j;
while(1)
{
j = 0;
while(j++ < 5)//over all operators
{i = 0;
result = numbers[0];//start with first element
while(i < arrlen - 2)//over all numbers, exclude the result
{
result = operate(j, result, numbers[++i]);
//something like this...this does not work correctly
//it might give you a hint in the right direction
if(result == numbers[arr_len - 1])//compare to last element
return 0;
}
}
}
return 0;
}
Following may help:
// increment v where each value is a digit with maximal value maxSize
// so {0,1,2}, 3 lead to {0,2,0}
// return false on overflow.
bool increment(std::vector<int>& v, int maxSize)
{
for (auto it = v.rbegin(); it != v.rend(); ++it) {
++*it;
if (*it != maxSize) {
return true;
}
*it = 0;
}
return false;
}
// display something like 1 + 2 * 3 = 9 // with the following meaning ((1 + 2) * 3) = 9
void display(const std::vector<double>& operands, const std::vector<int>& operators, double total)
{
const char operators_string[] = "+-*/^%";
std::cout << operands[0];
for (std::size_t i = 0; i != operators.size(); ++i) {
std::cout << " " << operators_string[operators[i]] << " " << operands[i + 1];
}
std::cout << " = " << total << std::endl;
}
// Compute something like {1 2 3 4}, {+ * /} as (((1 + 2) * 3) / 4)
double compute(const std::vector<double>& operands, const std::vector<int>& operators)
{
std::function<double(double, double)> fs[] = {
[](double a, double b) { return a + b; },
[](double a, double b) { return a - b; },
[](double a, double b) { return a * b; },
[](double a, double b) { return a / b; },
[](double a, double b) { return pow(a, b); },
[](double a, double b) { return fmod(a, b); },
};
double res = operands[0];
for (std::size_t i = 0; i != operators.size(); ++i) {
res = fs[operators[i]](res, operands[i + 1]);
}
return res;
}
void display_combinaison(const std::vector<double>& operands, double total)
{
std::vector<int> operators(operands.size() - 1);
do {
if (compute(operands, operators) == total) {
display(operands, operators, total);
}
} while (increment(operators, 6));
}
Live example