How to compare extracted digits in C++ - c++
I'm trying to implement the Bulls & Cows game and I have a logic problem. I am explicitly checking if each digit is either equal to a digit in the corresponding index (bulls) or at other indexes (cows). The value that I check with (4321) should yield "0 bulls and 4 cows" but it instead gives me "0 bulls and 3 cows.
Here is my code (and I apologize for the code repetition. I am also wondering if anyone has recommendations to make this code smaller):
#include <iostream>
#include <vector>
using namespace std;
int main() {
int guessValue = 1234;
int guess;
int bulls = 0;
int cows = 0;
cout << "Enter a 4 digit guess: ";
cin >> guess;
int firstValue = (guess % 10000) / 1000;
int secondValue = (guess % 1000) / 100;
int thirdValue = (guess % 100) / 10;
int fourthValue = guess % 10;
if (firstValue == ((guessValue % 10000) / 1000)) {bulls += 1;}
else if(firstValue == ((guessValue % 1000) / 100) ||
firstValue == ((guessValue % 100) / 10) ||
firstValue == (guess % 10))
{cows += 1;}
if (secondValue == ((guessValue % 1000) / 100)) {bulls += 1;}
else if (secondValue == ((guessValue % 10000) / 1000) ||
secondValue == ((guessValue % 100) / 10) ||
secondValue == (guess % 10))
{cows += 1;}
if (thirdValue == ((guessValue % 100) / 10)) {bulls += 1;}
else if (thirdValue == ((guessValue % 10000) / 1000) ||
thirdValue == ((guessValue % 1000) / 100) ||
thirdValue == (guess % 10))
{cows += 1;}
if (fourthValue == (guessValue % 10)) {bulls += 1;}
else if (fourthValue == ((guessValue % 10000) / 1000) ||
fourthValue == ((guessValue % 1000) / 100) ||
fourthValue == (guessValue % 100) / 10)
{cows += 1;}
cout << bulls << " bulls and " << cows << " cows" << endl;
}
I am also wondering if anyone has recommendations to make this code smaller
First of all use std::vector to keep separate digits:
std::vector<int> split( int v )
{
std::vector<int> r;
while( v ) {
r.push_back( v % 10 );
v /= 10;
}
return r;
}
Second, use standard algo std::count_if:
auto bulls = std::count_if( guessv.begin(), guessv.end(),
[it = targetv.begin()]( int i ) mutable
{ return i == *it++; } );
auto cows = std::count_if( guessv.begin(), guessv.end(),
[s = std::set<int>{ targetv.begin(), targetv.end() }]( int i )
{ return s.count( i ); } );
second one is actually counts cows and bulls, so it needs to be adjusted:
cows -= bulls;
live example
2 concepts that absolutely you need to master: loops and functions. First create some helpful functions.
These are the functions you could built your program upon:
int get_digit(int number, int order)
with example test cases:
get_digit(7895, 0) == 5
get_digit(7895, 1) == 9
get_digit(7895, 2) == 8
get_digit(7895, 3) == 7
then:
bool has_digit(int number, int digit)
with example test cases:
has_digit(7895, 1) == false
has_digit(7895, 8) == true
has_digit(7895, 5) == true
has_digit(7895, 0) == false
has_digit(7000, 0) == true
then:
bool matches_digit(int a, int b, int order)
with test cases:
matches_digit(1239, 4269, 0) == true
matches_digit(1239, 4269, 1) == false
matches_digit(1239, 4269, 2) == true
matches_digit(1239, 4269, 2) == false
and finally:
int get_cow(int a, int b)
int get_bull(int a, int b)
int main()
This is a top-down design, bottom-up implementation approach. First you think of the big picture and figure out what small pieces you need (functions) and then start implementing from the smallest most independent functions and step by step combine then into higher functions until you reach main.
This is my solution and it works. Basically I had to create a function to extract each digit and store them into a vector that can be applied to both the model and the guess. Then I used the find() method of the <algorithm> library to see if the digits exist in the guess vector and if yes, at which position compared to the model vector. Same position equals 1 bull and different position equals 1 cow. I am going to add more to this program, such as generating the model randomly and looping the program after each round so the user doesn't have to restart the game.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> getDigits(int modelValue) {
vector<int> vectorValue;
int extractedDigit = 0;
int modulant = 10000;
int divisor = 1000;
for (int i = 0; i < 4; i++) {
extractedDigit = (modelValue % modulant) / divisor;
vectorValue.push_back(extractedDigit);
modulant /= 10;
divisor /= 10;
}return vectorValue;
}
int main() {
int model = 1234;
int guess = 0000;
int bulls = 0;
int cows = 0;
int counter = 1;
cout << "Enter a value to guess: ";
cin >> guess;
vector<int> modelVector = getDigits(model);
vector<int> guessVector = getDigits(guess);
for (int i = 0; i < 4; i++) {
if (find(modelVector.begin(), modelVector.end(), guessVector[i]) != modelVector.end()) {
if (modelVector[i] == guessVector[i]) {bulls += 1;}
else { cows += 1; }
}
}cout << "There are " << bulls << " bulls and " << cows << " cows"<< endl;
}
Related
The next prime number
Among the given input of two numbers, check if the second number is exactly the next prime number of the first number. If so return "YES" else "NO". #include <iostream> #include <bits/stdc++.h> using namespace std; int nextPrime(int x){ int y =x; for(int i=2; i <=sqrt(y); i++){ if(y%i == 0){ y = y+2; nextPrime(y); return (y); } } return y; } int main() { int n,m, x(0); cin >> n >> m; x = n+2; if(n = 2 && m == 3){ cout << "YES\n"; exit(0); } nextPrime(x) == m ? cout << "YES\n" : cout << "NO\n"; return 0; } Where is my code running wrong? It only returns true if next number is either +2 or +4. Maybe it has something to do with return statement.
I can tell you two things you are doing wrong: Enter 2 4 and you will check 4, 6, 8, 10, 12, 14, 16, 18, ... for primality forever. The other thing is y = y+2; nextPrime(y); return (y); should just be return nextPrime(y + 2); Beyond that your loop is highly inefficient: for(int i=2; i <=sqrt(y); i++){ Handle even numbers as special case and then use for(int i=3; i * i <= y; i += 2){ Using a different primality test would also be faster. For example Miller-Rabin primality test: #include <iostream> #include <cstdint> #include <array> #include <ranges> #include <cassert> #include <bitset> #include <bit> // square and multiply algorithm for a^d mod n uint32_t pow_n(uint32_t a, uint32_t d, uint32_t n) { if (d == 0) __builtin_unreachable(); unsigned shift = std::countl_zero(d) + 1; uint32_t t = a; int32_t m = d << shift; for (unsigned i = 32 - shift; i > 0; --i) { t = ((uint64_t)t * t) % n; if (m < 0) t = ((uint64_t)t * a) % n; m <<= 1; } return t; } bool test(uint32_t n, unsigned s, uint32_t d, uint32_t a) { uint32_t x = pow_n(a, d, n); //std::cout << " x = " << x << std::endl; if (x == 1 || x == n - 1) return true; for (unsigned i = 1; i < s; ++i) { x = ((uint64_t)x * x) % n; if (x == n - 1) return true; } return false; } bool is_prime(uint32_t n) { static const std::array witnesses{2u, 3u, 5u, 7u, 11u}; static const std::array bounds{ 2'047u, 1'373'653u, 25'326'001u, 3'215'031'751u, UINT_MAX }; static_assert(witnesses.size() == bounds.size()); if (n == 2) return true; // 2 is prime if (n % 2 == 0) return false; // other even numbers are not if (n <= witnesses.back()) { // I know the first few primes return (std::ranges::find(witnesses, n) != std::end(witnesses)); } // write n = 2^s * d + 1 with d odd unsigned s = 0; uint32_t d = n - 1; while (d % 2 == 0) { ++s; d /= 2; } // test widtnesses until the bounds say it's a sure thing auto it = bounds.cbegin(); for (auto a : witnesses) { //std::cout << a << " "; if (!test(n, s, d, a)) return false; if (n < *it++) return true; } return true; } And yes, that is an awful lot of code but it runs very few times.
Something to do with the return statement I would say so y = y+2; nextPrime(y); return (y); can be replaced with return nextPrime(y + 2); Your version calls nextPrime but fails to do anything with the return value, instead it just returns y. It would be more usual to code the nextPrime function with another loop, instead of writing a recursive function.
Time limit exceeded on minimum coin change problem(Dynamic Programming Implementation) on CodeChef and CodeForces
I have encountered the minimum coin change problem on CodeChef and CodeForces. On both sites I have submitted my implementation using DP. This implementation given TLE error on both sites. Unfortunately, I cannot find any other implementation of this problem. I am linking the problems - CodeChef - https://www.codechef.com/problems/FLOW005 CodeForces - https://codeforces.com/problemset/problem/996/A Here is my code(CodeChef implementation) - int main() { int T{}; std::cin >> T; for (int i = 1; i <= T; ++i) { int N{}; std::cin >> N; std::vector <int> arr(N + 1); for (int i = 0; i < N + 1; ++i) { arr[i] = minCoins(i, arr); } std::cout << arr[N] << std::endl; } return 0; } The minCoins Function - int minCoins(int x, std::vector <int> arr) { if (x == 0) return 0; else if (x == 1 || x == 2 || x == 5 || x == 10 || x == 50 || x == 100) return 1; int min{ 1 + arr[x - 1]}; if (x > 100) min = std::min(min, l + arr[x - 100]); if (x > 50) min = std::min(min, 1 + arr[x - 50]); if (x > 10) min = std::min(min, 1 + arr[x - 10]); if (x > 5) min = std::min(min, 1 + arr[x - 5]); if (x > 2) min = std::min(min, 1 + arr[x - 2]); if (x > 1) min = std::min(min, 1 + arr[x - 1]); return min; } There is no problem of integer overflow as I chose int data type after reading the constraints. Also, if anyone would like to suggest how I can remove the if ladder and replace it with something simpler, I would appreciate the help. Also, thank you for taking the time to read my question :)
#include <iostream> int main() { int tests; std::cin >> tests; int value; while (tests--) { int coinCount = 0; std::cin >> value; while (value > 0) { if (value >= 100) { coinCount += (value / 100); value %= 100; } else if (value >= 50) { coinCount += (value / 50); value %= 50; } else if (value >= 10) { coinCount += (value / 10); value %= 10; } else if (value >= 5) { coinCount += (value / 5); value %= 5; } else if (value >= 2) { coinCount += (value / 2); value %= 2; } else if (value >= 1) { coinCount += (value / 1); value = 0; } } std::cout << coinCount << '\n'; } } Tested on CodeChef and passed with execution time of 0.00. The currency systems shown in the problems are designed in such a way that the greedy choice is the correct choice. This holds true for very nearly if not all existing currency systems. If you require proof, http://www.cs.toronto.edu/~denisp/csc373/docs/greedy-coin-change.pdf
Prime checker doesn't include some multipliers of the number 10
I need to make a program that will check whether or not the number typed in (a) and its mirrored self (a1) are both prime numbers. I got it to work up to the point where I input a multiplier of 10, in which case it declares it as a prime number, which it clearly isn't. I've already tried setting the condition: if ( a % 10 = 0 ) {//declare it as non prime} After having done that, I would always get a return value of 0 after entering the number. Also tried declaring : if ( a == 1 ) {//declare it as a non prime} which fixed it for multipliers of 10 up to 100, but the rest would give me the previously stated error. My go at it: #include <iostream> using namespace std; int main() { int a, a1, DN; cin >> a; DN = a; a1 = 0; for (; a != 0;) { a1 *= 10; a1 = a1 + a % 10; a /= 10; } int este_prim, i, este_prim2; este_prim = 1; i = 2; este_prim2 = 1; while (i < DN && i < a1) { if (DN % i == 0) { este_prim = 0; } ++i; } if (a1 > i && a1 % i == 0) { este_prim2 = 0; } ++i; if (a == 1) { este_prim = 0; } if (a1 == 1) { este_prim2 = 0; } if (este_prim2 == 1 && este_prim == 1) { cout << "DA"; } else { cout << "NU"; } return 0; } I'm a complete newbie at this so any help would be appreciated. Cheers!
Your loop checks if DN is prime, but it doesn't check if a1 is prime. And this block of code is something I do not understand. if (a1 > i && a1 % i == 0) { este_prim2 = 0; } So just remove that. Use this worthy helper function to detect if a positive number is prime: bool isPrime(int x) { if (x <= 1) return false; // 2 is the only even prime if (x == 2) return true; // any other even number is not prime if ((x % 2) == 0) return false; // try dividing by all odd numbers from 3 to sqrt(x) int stop = sqrt(x); for (int i = 3; i <= stop; i += 2) { if ((x % i) == 0) return false; } return true; } And then your code to detect if DN and it's mirror, a1 are both prime is this: int main() { int a, a1, DN; cin >> a; DN = a; a1 = 0; for (; a != 0;) { a1 *= 10; a1 = a1 + a % 10; a /= 10; } bool este_prim, este_prim2; este_prim = isPrime(DN); este_prim2 = isPrime(a1); if (este_prim2 && este_prim) { cout << "DA"; } else { cout << "NU"; } }
C++ trying to call functions from main
I'm trying to write a function that will find the reverse of a number, so if 1234 is input, the reverse is 4321. #include <iostream> using namespace std; int reverse(int); int main() { cout << "This is the special difference calculator. Please enter positive integers: " << endl; reverse(); } int reverse(int num) { int num, remainder, reversenum; cin >> num; while (num != 0) { remainder = num % 10; reversenum = reversenum * 10 + remainder; } return reversenum; } I also tried making a variable in main and setting it equal to reverse(int) but it showed it was wrong. I honestly have no idea what I'm doing so any help would be greatly appreciated!
There are a few logic errors in your code. Try the following code ( please note the comments ): #include <iostream> using namespace std; int reverse(); int main() { cout << "This is the special difference calculator. Please enter positive integers: " << endl; reverse(); } int reverse() { int num, remainder, reversenum=0;//reversenum should be initialized to zero cin >> num; while (num != 0) { remainder = num % 10; num = num/10; // Add this line so that while statement works correctly reversenum = reversenum * 10 + remainder; } return reversenum; }
You still do not understand how functions work. Your logic was wrong (as far I was concerned) I coded this for 2 digit numbers. I left you the math equations for 3, 4, and 5 digit numbers. Use nested loops or input manipulation to choose the correct equation. Read the following stuff to learn more about functions. Stack Overflow is not for homework help, next time do more reading and try more in your code before asking for help. Read: http://www.cplusplus.com/doc/tutorial/functions/ #include <iostream> using namespace std; int rev_function (int num) { int r; //For 2 digit numbers r = (10)*(num % 10) + (num - (num % 10)) / 10 ; //For 3 digit numbers //f(x) = (100)(x % 10) + ((x - (x % 10)) % 100) + (x - (x % 100)) / 100 //For 4 digit numbers //f(x) = (1000)(x % 10) + ((x - (x % 10)) % 100) * 10 + ((x - (x % 100)) % 1000) / 10 + (x - (x % 1000)) / 1000 //For 5 digit numbers //f(x) = (10000)(x % 10) + ((x - (x % 10)) % 100) * 100 + ((x - (x % 100)) % 1000) + ((x - (x % 1000)) % 10000) / 100 + (x - (x % 10000)) / 10000 return r; } int main () { int z; int num; cout << "\nThis is the special difference calculator."; cout << "\n Please enter positive integers: "; cin >> num; z = rev_function (num); cout << "The result is " << z; } So the output would be: This is the special difference calculator. Please enter positive integers: 12 The result is 21
Project Euler #27 [closed]
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center. Closed 9 years ago. I'm challenging myself in Project Euler but currently stuck on problem 27, in which the problem states: Euler published the remarkable quadratic formula: n² + n + 41 It turns out that the formula will produce 40 primes for the consecutive values n = 0 to 39. However, when n = 40, 402 + 40 + 41 = 40(40 + 1) + 41 is divisible by 41, and certainly when n = 41, 41² + 41 + 41 is clearly divisible by 41. Using computers, the incredible formula n² 79n + 1601 was discovered, which produces 80 primes for the consecutive values n = 0 to 79. The product of the coefficients, 79 and 1601, is 126479. Considering quadratics of the form: n² + an + b, where |a| 1000 and |b| 1000 where |n| is the modulus/absolute value of n e.g. |11| = 11 and |4| = 4 Find the product of the coefficients, a and b, for the quadratic expression that produces > the maximum number of primes for consecutive values of n, starting with n = 0. I wrote the following code, which gives me the answers pretty quick but it is wrong (it spits me (-951) * (-705) = 670455). Can somebody check my code to see where is/are my mistake(s)? #include <iostream> #include <vector> #include <cmath> #include <time.h> using namespace std; bool isprime(unsigned int n, int d[339]); int main() { clock_t t = clock(); int c[] = {13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597,1601,1607,1609,1613,1619,1621,1627,1637,1657,1663,1667,1669,1693,1697,1699,1709,1721,1723,1733,1741,1747,1753,1759,1777,1783,1787,1789,1801,1811,1823,1831,1847,1861,1867,1871,1873,1877,1879,1889,1901,1907,1913,1931,1933,1949,1951,1973,1979,1987,1993,1997,1999,2003,2011,2017,2027,2029,2039,2053,2063,2069,2081,2083,2087,2089,2099,2111,2113,2129,2131,2137,2141,2143,2153,2161,2179,2203,2207,2213,2221,2237,2239,2243,2251,2267,2269,2273,2281,2287,2293,2297,2309,2311}; int result[4]; result[3] = 0; for (int a = -999; a < 1000; a+=2) { for (int b = -999; b < 1000; b+=2) { bool prime; int n = 0, count = 0; do { prime = isprime(n*n + a*n + b, c); n++; count++; } while (prime); count--; n--; if (count > result[3]) { result[0] = a; result[1] = b; result[2] = n; result[3] = count; } } if ((a+1) % 100 == 0) cout << a+1 << endl; } cout << result[0] << endl << result[1] << endl << result[2] << endl << result[3] << endl << clock()-t; cin >> result[0]; return 0; } bool isprime(unsigned int n, int d[339]) { int j = 0, l; if ((n == 2) || (n == 3) || (n == 5) || (n == 7) || (n == 11)) return 1; if ((n % 2 == 0) || (n % 3 == 0) || (n % 5 == 0) || (n % 7 == 0) || (n % 11 == 0)) return 0; while (j <= int (sqrt(n) / 2310)) { for (int k = 0; k < 339; k++) { l = 2310 * j + d[k]; if (n % l == 0) return 0; } j++; } return 1; }
There's a bug in isprime function. In your function, you check all 2310 * j + d[k] where j < int (sqrt(n) / 2310)) to ensure the target n is a prime number. However, an additional condition that l < sqrt(n) is also required, or you will over-exclude some prime numbers. For example, when a = 1, b = 41 and n = 0, your function will check whether 41 is a prime number starting from j = 0. So whether 41 can be divisible by 2310 * 0 + d[7] = 41 is also verified, which leads to a false return. This version should be correct: bool isprime(unsigned int n, int d[]) { int j = 0, l; if ((n == 2) || (n == 3) || (n == 5) || (n == 7) || (n == 11)) return 1; if ((n % 2 == 0) || (n % 3 == 0) || (n % 5 == 0) || (n % 7 == 0) || (n % 11 == 0)) return 0; double root = sqrt(n); while (j <= int (root / 2310)) { for (int k = 0; k < 339; k++) { l = 2310 * j + d[k]; if (l < root && n % l == 0) return 0; } j++; } return 1; }