I have some CPP code to generate Lorem Ipsum style text. It works when I ask it for one sentence at a time, but when I tell it to mass generate sentences it generates tons of sentences that are just spaces and then periods. Here's the code (modified for confidentiality):
srand(time(NULL));
string a[9327] = {"Str1", "Str2", "Str3" . . .};
int loop_1 = 0;
int loop_2 = 0;
while (loop_2 <= 100000) {
while (loop_1 <= (rand() % 38) + 2) {
int value = rand() % (9327 - (rand() % (9327 - (rand() % (9327 - (rand() % 9327))))));
cout << a[value] << " ";
loop_1 = loop_1 + 1;}
cout << "\b. ";
loop_2 = loop_2 + 1;
}
I'm sorry if this is an incompetent question. I'm a conlanger/composer normally but I had to throw together some code for a project––so I'm still just barely learning C++.
Okay, I mean, this code doesn't make a lot of sense but to answer the question, note that the only way the inner loop can not issue random strings is if it never runs and it will not run if loop_1 is greater than (rand() % 38) + 2 which is a random number from 2 to 40. Once loop_1 is greater than 40 the inner loop can never run, because loop_1 only increases.
But anyway, before that occurs, if you want the inner loop to definitely run then test that it does ... Also might as well get rid of loop_2 because it isn't doing anything once loop_1 is greater than 40.
Replacing 9327 with 7, I get
int main() {
srand(time(NULL));
string a[7] = { "aaaaaaaaaa ", "bbbbbbbb ", "ccccccccccccc ", "dddddddd ", "eeeeeeeeeee ", "ffffffffff ", "ggggggg "};
int loop_1 = 0;
while (loop_1 < 40) {
auto num = (rand() % 38) + 2;
if (loop_1 > num) {
continue;
}
while (loop_1 <= num) {
int value = rand() % (7 - (rand() % (7 - (rand() % (7 - (rand() % 7))))));
cout << a[value] << " ";
loop_1 = loop_1 + 1;
}
cout << "\b. ";
}
}
Related
I have to print 8 terms of the sequence as
1, 2, 4, 8, 16, 22, 26, 38, ....
I have completed my logic till 16 that every new term is the previous term multiplied by 2. And after 16 the logic is that we divide that part into two as
26 = 22 + (2 * 2)
Till now what I have done is
int x = 1, num, num1, n = 1;
while (n <= 10)
{
while (n <= 4)
{
if (n == 1)
{
cout << x << ", ";
}
num = x % 10;
num1 = num % 10;
x = x * 2;
cout << x << ", ";
n++;
}
if (x == 16)
{
num = x % 10;
num1 = num % 10;
x = x + (num * num1) - 30;
cout << x << ", ";
}
else
{
num = x % 10;
num1 = num % 10;
x = x + (num * num1);
cout << x << ", ";
}
n++;
}
Apparently we just add the product of all digits to current number. That works fine for 1, 2, 4, 8 as well (e. g. 4 = 2 + (2)), so no need to have any special handling. However, apparently we need to ignore zeros, otherwise we wouldn't change after 102 any more...
So we can simplify the altorithm quite a bit:
unsigned int number = 1; // start value
std::cout << number; // OK, would require special handling for n == 0...
while(n--) // you could ask the user to input n or just set it to 10
// (I consider this variant a bit more elegant)
{
unsigned int product = 1;
unsigned int tmp = number;
// now iterate as long as you have more digits!
while(tmp)
{
unsigned int modulo = tmp % 10;
tmp /= 10;
// neat little trick: if modulo != 0, comparison is false, which is
// converted to 0, which is neutral for OR operation; otherwise, we
// get 0 | 1, which is neutral for multiplication...
product *= modulo | (modulo == 0);
}
number += product;
std::cout << ", " << number;
}
This would work fine even for fare more numbers than just the first ten ones (until overflow of either the product or the sum occurs...).
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;
}
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
I'm trying to accomplish the following:
a) define a 12x12 matrix using (pseudo) random numbers
b) output this matrix
c) alter only the diagonal of this matrix (e.g. add a given number to [R0][C0], add a given number to [R1][C1], add a given number to [R2][C2]
I'm able to accomplish 'a' and 'b' without any problem. I'm able to accomplish 'c' to a limited degree (the results are not what I would expect).
Here's my code:
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
using namespace std;
const int N = 12;
const int P = 12;
int Matrix_M[N][P] = {0};
int rowSum[N] = {0};
int colSum[P] = {0};
void generateArray();
void addError();
int main()
{
generateArray();
addError();
return 0;
}
void RainGen()
{
// sets the seed for the number generator
unsigned setSeed = 1023;
srand(setSeed);
// generates the matrix using pseudo-random numbers
for (int i = 0; i < N; i++)
{
for (int j = 0; j < P; j++)
{
Matrix_M[i][j] = rand() % 100;
// outputs the raw matrix
cout << left << setw(4) << Matrix_M[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
}
void addError()
{
// sets the seed for the number generator
unsigned setSeed = 1023;
srand(setSeed);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < P; j++)
{
// adds 100 to the previously-generated number in the original matrix
if (i == j)
{
Matrix_M[i][j] = rand() % 100 + 100;
}
// outputs the 'adjusted' matrix
cout << left << setw(4) << Matrix_M[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
}
Currently, this code compiles but does not give the expected result. For example, I'm seeing the following in the original matrix:
79 59 41 39 ...
24 84 95 0 ...
92 96 37 13 ...
90 58 65 13 ...
. . . .
. . . .
. . . .
And, in the adjusted matrix, I'm seeing:
179 59 41 39 ...
24 159 95 0 ...
92 96 141 13 ...
90 58 65 139 ...
. . . .
. . . .
. . . .
[0][0] of this matrix is correct. The other elements of the DIAGONAL in the 'adjusted' matrix are not correct. For example, in [1][1], we see 159. I would expect to see 184 in [1][1]. But, the code is taking the element in the first row of each column, adding 100 to it, then placing that value in the desired position in the diagonal (e.g. in the case of [3][3], we have 100 being added to 39, which is the element in [0][3]. This is the code that's causing the issue:
for (int i = 0; i < N; i++)
{
for (int j = 0; j < P; j++)
{
// adds 100 to the previously-generated number in the original matrix
if (i == j)
{
Matrix_M[i][j] = rand() % 100 + 100;
}
// outputs the 'adjusted' matrix
cout << left << setw(4) << Matrix_M[i][j] << " ";
}
cout << endl;
}
I also thought about using the following 'brute force' method:
Matrix_M[0][0] = (rand() % 100) + 100;
Matrix_M[1][1] = (rand() % 100) + 200;
Matrix_M[2][2] = (rand() % 100) + 300;
Matrix_M[3][3] = (rand() % 100) + 400;
Matrix_M[4][4] = (rand() % 100) + 500;
Matrix_M[5][5] = (rand() % 100) + 600;
Matrix_M[6][6] = (rand() % 100) + 700;
Matrix_M[7][7] = (rand() % 100) + 800;
Matrix_M[8][8] = (rand() % 100) + 900;
Matrix_M[9][9] = (rand() % 100) + 1000;
Matrix_M[10][10] = (rand() % 100) + 1100;
Matrix_M[11][11] = (rand() % 100) + 1200;
But, this too is not yielding the expected results. Can someone offer some guidance on how to properly address this problem?
Thanks very much in advance.
-Ryan
Your problem comes from the fact that you re-run the random generator. Since you use the same seed again, the numbers are the same:
First, you generate your number (79,59,41,...) and put it in your matrix.
Then, you generate the same numbers and put them in the diagonal of the matrix after having added 100 to it.
If you want to accomplish your goal, you must not re-run the random generator but use the previous value of the matrix. Instead of
if (i == j)
{
Matrix_M[i][j] = rand() % 100 + 100; //re-runs rand()
}
You want to do:
if (i == j)
{
Matrix_M[i][j] += 100;
}
2 things:
You do not need a nested loop for modifying the diagonal. Use the fact that both indices are the same, i.e. Matrix_M[i][i] is**always** a diagonal
When youupdate the element you are making it incorrectly. What you do is Matrix_M[i][j] = rand() % 100 + 100; which generates a new number when what you need is to update the existing one
Looks like you are trying to verify that the RNG works "correctly". But what you do is as follows:
first loop: you generate a new random number for EACH element
second loop: you only generate new numbers for updated elements. That is where you discrepancy is :)
You can change your second loop the following way to do what you need:
for (int j = 0; j < P; j++)
{
int num = rand() % 100 + 100; // this will ensure the SAME random sequence
if (i == j)
{
Matrix_M[i][j] = num;
}
Your problem is that in the addError() function you only set matrix elements on the diagonal but when initializing the matrix you use rand for every element. Therefore you'll find after a call of addError() the elements of the first row + 100 in your diagonal. What you can do is to add an else-clause where you just call rand, i.e.
if(i == j) {
Matrix_M[i][j] = rand() % 100 + 100;
}
else {
rand();
}
I'm trying to implement a function to add two overly large (let's say 1000 digit long) numbers stored in strings. I'm having problems with correct conversions so I can add numbers correctly.
So far, this is what I've done:
string addBegin (string low, string high, int diff)
{
for (int i = 0; i <= diff; i++)
low = "0" + low;
high = "0" + high;
cout << "low: " << low << "\nhigh: " << high << endl;
string result;
int sum, carry = 0;
for (int i = low.length()-1; i >= 0; i--)
{
sum = (int)low[i] + (int)high[i] + carry;
carry = 0;
if (sum > 9)
{
sum -= 10;
carry = 1;
}
result = to_string(sum) + result;
}
return result;
}
string add (string a, string b)
{
int diff = a.length() - b.length();
if (diff <= 0) return addBegin(a, b, abs(diff));
else return addBegin(b, a, diff);
}
int main (void)
{
string x = add("52","205");
cout << "result: " << x << endl;
return 0;
}
Output:
low: 0052
high: 0205 //the first zero is for potential carry
result: 87899293 //wrong, should be 0257
The result here is made of 4 numbers: 87, 89, 92 and 93. That is obviously wrong, I did some unwanted additions with ASCII values. Any ideas how to make this work? Or is there, by any chance, some ridiculously simple way to add two veeeeery long numbers?
sum = (int)low[i] + (int)high[i] + carry;
This adds the values of the character encodings in e.g. ASCII. You want to subtract '0' from the encoding to get the numeric value.
sum = low[i] - '0' + high[i] - '0' + carry;
Do not forget subtracting '0' from low[i] and high[i] when doing the math.
(int)low[i] is 0x30..0x39 for chars '0'..'9'.
A problem is that you use
sum = (int)low[i] + (int)high[i] + carry;
which should be
sum = low[i] - '0' + high[i] - '0' + carry;