I am doing some c++ practice and trying to write a program to count the amount of times a dice combination is rolled after 10000 attempts. I have used a 2D array to store every possible dice combination, and I perform 10000 rand()%6+1 and increments the value in the memory allocation it randoms.
This is my attempt.
cout << "\nDice roll analyser" << endl;
const int first = 6;
const int second = 6;
int nRolls[first][second];
int count = 0;
while (count < 10000){
nRolls[rand()%6+1][rand()%6+1]+=1;
count++;
}
for (int i=0;i<first;i++){
for (int j=0;j<second;j++){
cout << nRolls[i][j] << " ";
}
}
This is the output that I get;
0 0 0 0 0 0 0 269 303 265 270 264 228 289 272 294 290 269 262 294 303 277 265 294 288 266 313 274 301 245 317 276 292 284 264 260
What I am trying to achieve is the amount of times each combination is rolled e.g. how many times 1, 6 is rolled etc.
You never update your count.
For something where you want to run a code segment n times, where right now n = 10000, this is the general way you wanna do it.
for (int i = 0; i < 10000; ++i)
{
//loop code.
}
additionally, myVariable+=1 can always be simplified to either ++myVariable or myVariable++ (if you aren't use the value of myVariable right when you are assigning it, it is better to use the first one. More info on pre/post increment can be found here: http://gd.tuwien.ac.at/languages/c/programming-bbrown/c_015.htm
so instead of nRolls[rand()%6+1][rand()%6+1]+=1;
you can instead do
++(nRolls[rand()%6+1][rand()%6+1]);
Additionally, arrays are zero-indexed, meaning when you do rand()%6+1 you are restricting the values from 1 to 6 and leaving out the 0 position of an array, which is the first one, so consider instead just using
++(nRolls[rand()%6][rand()%6]);
then, to find out how often you roll a (i,j), where i and j are between 1 and 6,
cout << "(" << i << "," << j << "):" << nRolls[i-1][j-1] << endl;
You will have a problem here because you are adding +1 to rand()%6 you will never increment the count of any of elements with index zero. The minimum element index you allow to be incremented starts at 1.
OK, thanks for the help. This is the updated code that displays correctly!
cout << "\nDice roll analyzer" << endl;
srand(time(0));
const int first = 6;
const int second = 6;
int nRolls[first][second];
int count = 0;
while (count < 10000){
nRolls[rand()%6][rand()%6]++;
count++;
}
for (int i=0;i<first;i++){
for (int j=0;j<second;j++){
cout << "(" << i+1 << "," << j+1 << ")" << nRolls[i][j] << endl;
}
}
Related
I want to make a program that works with integers that were inputted using space and not enter. when you input the integers 12 80 33 99 with space between each one of them, then the code will separate the integers and put them into an array.
I'm using codeblocks, C++
int main(){
int A;
int j [10] ={0,0,0,0,0,0,0,0,0,0};
cin >> A;
string As;
bool code = true;
int hasil [A][10];
getline(cin,As);
for (int i = 0 ; i < A ; i++){
while (code){
if( cin.get() != '\n'){
cin >> hasil[i][j[i]];
j[i]++;
}else{ code = false;}
}}
for (int i = 0 ;i < A ; i++){
for (int x = 0; x != j[i]; x++){
cout << hasil[i][x]<< " " ;
}
cout << " " << endl;
}
return 0;}
When I input 25 17 70 88, I expected the output to be 25 17 70 88 too, but the actual output was 5 17 70 88. Where is my first 2?
Your 2 was eaten by the call to cin.get() which reads one character which your code then throws it away.
I can't understand exactly what you are trying to do but i can see an error in your code which might cause undefined behaviour. int hasil[A][10] is a static array which means compiler must know its size at compile time, however A is not a compile time constant. If you don't know the size of your array you should use a pointer instead or even better a std container such as std::vector.
To make your code more readable you can also delete the code variable and replace your first for loop body with
while(cin.get() != '\n)
{
cin >> .....
...
}
I am using a ranged for loop to input random values into a vector. However, when i output the values of the vector there is a set of trailing zeros. I do not know where they came from.
#include <iostream>
#include <vector>
#include <array>
#include <cstdlib>
#include <iomanip>
using namespace std;
int double1(int number)
void double2 (int &number);
void double3 (int *number);
void triple1 (int array1[], int size);
void triple2 (array<int, 10> &array2);
void triple3 (vector<int> *array3);
int main(){
int array1[10];
int copy_array1[10];
array<int, 10> array2;
array<int, 10> copy_array2;
vector<int> array3(10);
vector<int> copy_array3(10);
for(int x = 0; x <10; x++){
array1[x] = rand() % (101 -50) + 50;
}
for(auto &n : array2){
n = rand() % (101 -50) + 50;
}
for(auto a : array3){
array3.push_back(rand() % (101 -50) + 50);
}
copy(begin(array1), end(array1), begin(copy_array1));
copy_array3 = array3;
copy_array2 = array2;
cout <<"Arrays loaded with random numbers from 50 - 100" << endl;
cout << "=====================================================" << endl;
cout <<"Array1: ";
for(int x = 0; x<10; x++){
cout << setw(5) << left << array1[x];
}
cout << endl;
cout <<"Array2: ";
for(int x:array2){
cout << setw(5) << left << x;
}
cout << endl;
cout <<"Array3: ";
for(int x:array3){
// if( x != 0)
cout << setw(5) << left << x;
}
cout << endl;
double1(array1);
}
The output gives me:
Arrays loaded with random numbers from 50 - 100
=====================================================
Array1: 91 55 60 81 94 66 53 83 84 85
Array2: 94 94 75 98 66 82 87 58 83 80
Array3: 0 0 0 0 0 0 0 0 0 0 56 68 76 50 87 90 80 100 82 55
I have to use a ranged for loop. I have been confused on what those extra zeros are doing there in array3. I set the size of the vector to ten, but using .size() reveals the size is actually 20. Why did the vector put ten zeros in front of my random values?
There are extra zeros because you put them there. I'm not kidding, you did it right here:
vector<int> array3(10);
The std::vector constructor you used is the one that accepts how many elements the vector should be initialized with. So it allocates space, and then value initializes them, which for integers means zero initialize.
At this point, array3 isn't an empty vector with space for 10 more integers. It's a vector with 10 integers (all 0) already present. So when you push_back some more, it's all added after those existing items.
If you want to overwrite them, like you do with std::array, then you can employ the exact same loop you did for array2. If on the other hand you really want to use push_back, then you need to construct an empty vector (you may call reserve on it, after construction), and push_back into it 10 times. A range-based for won't work in this case, because the vector is constructed empty. So the loop will be over an empty range, and so just won't do anything.
I'm a bit confused about this exercise in the above mentioned book-
"The character 'b' is char('a'+ 1), 'c' is char('a'+ 2), etc. Use a loop to write out a table of characters with their corresponding integer values:
a 97
b 98
c 99
...
z 122"
The book has just gone over while loops, and I read a bit ahead as I was still confused as to how to do this without just listing out each value individually (which I assume isn't the point here), and the next section is about for loops. I thought that maybe you can somehow increase letters in the alphabet by 1 in a loop (so a -> b, b -> c, etc.), but if this is indeed possible, the book hasn't yet gone over how to accomplish this yet.
Thanks in advance, I'm working through this book alone in my spare time so I don't have a professor to ask questions like this, and the Try This exercises don't have their answers listed on Bjarne's website.
Just write a simple loop:
for(auto c = 'a';c <= 'z' ;c++)
cout<<c<<" "<<int(c)<<endl;
Here is my solution to your problem :)
int main (void) {
char c = 'a';
while (c <= 'z') {
std::cout << c << "\t" << c - 0 << '\n'; // c - 0 is convertion to int without cast
++c;
}
return 0;
}
The book is referring to the idea that you can iterate over integers and use the control variable in character arithmetic to get the table. For example, with integers you can iterate over the integers 0 to 25 with
int i = 0;
while (i <= 25) {
cout << i << endl;
i = i + 1; // or ++i
}
Now you can apply the problem hint char('a' + i) to get the rest of the answer. I'll let you work that out.
int main()
{
char ch = 'a';
int i = 0;
while(i < 26)
{
cout << (char)(ch + i) << "\t" << (ch + i) << "\n";
++i;
}
}
You can do something like this:
char ch = 'a';
for (int i = 0; i < 26; ++i)
cout << (char)(ch + i) << " " << (ch + i) << endl;
This will generate the output that you expect.
Here is one way to do it using the while loop:
#include <iostream>
int main()
{
int i = 0; //Initialize i to 0.
while (i < 26) // 0 - 25.
{
int val = 'a' + i; // char('a' + 1), int('a' + 1).
std::cout << char(val) << "\t" << int(val) << std::endl;
++i; //Increments the while loop variable i
}
return 0;
}
Output:
a 97
b 98
c 99
d 100
e 101
f 102
g 103
h 104
i 105
j 106
k 107
l 108
m 109
n 110
o 111
p 112
q 113
r 114
s 115
t 116
u 117
v 118
w 119
x 120
y 121
z 122
I included comments so that you can understand my thoughts and also so that it can be updated.
Here's the answer to the Chapter 4 Try this exercise for the book by Bjarne Stroustrup: Programming Principles and Practice Using C++:
// Description- Try this exercise using a while statement to provide a series of characters from the ASCII code.
#include "stdafx.h"
#include "Std_lib_facilities.h"
int main()
{
int i = 96; // Beginning/initialisation of the integers which will be converted to char (s) in cout.
while (i<122) // The limit for the while statement is the integer which will be safely converted to the last char.
{
cout << i + 1 << '\t'<< char (i+1)<<'\n'; ++i; // The first integer will be 1 plus the initial = 97. Then followed by a tab.
// Then followed by the integer 97 being safely converted to an char using the ASCII.
// The while loop in the two comments is repeated till 122 is converted safely to z.
}
}
I'm just learning c++, and I've come to my first problem. I'm using visual studio and c++11. this is the code:
cout << "Enter 5 numbers to add." << endl;
for (int i(0); i < 5; ++i) {
int x;
cin >> x;
intList.push_back(x);
}
for (int item:intList) {
sort(begin(intList), end(intList));
cout << item << " ";
total += item;
}
cout << endl;
cout << "Your total is " << total << endl;
As you can tell, it ask you to input 5 number and it adds them up. When I use cout, it output the contents of the vector correctly. As soon as I added the sort line, I had problems. It sorts the vector correctly, except it replaces the lowest value with the first value, even though it places it in the correct order. Example:
Enter 5 numbers to add.
87 95 61 43 2
87 43 61 87 95
Your total is 373
Also an additional question, is using item::intList the best/efficient way to iterate a vector.
I'm sure this is an obvious solution. Thanks.
You need to reposition the call to sort so that it's outside the for loop.
Currently your sort is invalidating the iterator (on its first call as thereafter it's a no-op) which is causing the effect you observe.
(I'm sure you know that you don't need to sort the vector in order to compute the total.)
I'm having a weird problem with an MPI program. Part of the code is supposed to be executed by the root (process zero) only, but process zero seems to execute it twice. For example,
root = 0;
if (rank == root) {
cout << "Hello from process " << rank << endl;
}
gives
Hello from process 0
Hello from process 0
This seems to only happen when I use 16 or more processes. I've been trying to debug this for quite a few days but couldn't.
Since I don't know why this is happening, I think I have to copy my entire code here. I made it nice and clear. The goal is to multiply two matrices (with simplifying assumptions). The problem happens in the final if block.
#include <iostream>
#include <cstdlib>
#include <cmath>
#include "mpi.h"
using namespace std;
int main(int argc, char *argv[]) {
if (argc != 2) {
cout << "Use one argument to specify the N of the matrices." << endl;
return -1;
}
int N = atoi(argv[1]);
int A[N][N], B[N][N], res[N][N];
int i, j, k, start, end, P, p, rank;
int root=0;
MPI::Status status;
MPI::Init(argc, argv);
rank = MPI::COMM_WORLD.Get_rank();
P = MPI::COMM_WORLD.Get_size();
p = sqrt(P);
/* Designate the start and end position for each process. */
start = rank * N/p;
end = (rank+1) * N/p;
if (rank == root) { // No problem here
/* Initialize matrices. */
for (i=0; i<N; i++)
for (j=0; j<N; j++) {
A[i][j] = N*i + j;
B[i][j] = N*i + j;
}
cout << endl << "Matrix A: " << endl;
for(i=0; i<N; ++i)
for(j=0; j<N; ++j) {
cout << " " << A[i][j];
if(j==N-1)
cout << endl;
}
cout << endl << "Matrix B: " << endl;
for(i=0; i<N; ++i)
for(j=0; j<N; ++j) {
cout << " " << B[i][j];
if(j==N-1)
cout << endl;
}
}
/* Broadcast B to all processes. */
MPI::COMM_WORLD.Bcast(B, N*N, MPI::INT, 0);
/* Scatter A to all processes. */
MPI::COMM_WORLD.Scatter(A, N*N/p, MPI::INT, A[start], N*N/p, MPI::INT, 0);
/* Compute your portion of the final result. */
for(i=start; i<end; i++)
for(j=0; j<N; j++) {
res[i][j] = 0;
for(k=0; k<N; k++)
res[i][j] += A[i][k]*B[k][j];
}
MPI::COMM_WORLD.Barrier();
/* Gather results form all processes. */
MPI::COMM_WORLD.Gather(res[start], N*N/p, MPI::INT, res, N*N/p, MPI::INT, 0);
if (rank == root) { // HERE is the problem!
// This chunk executes twice in process 0
cout << endl << "Result of A x B: " << endl;
for(i=0; i<N; ++i)
for(j=0; j<N; ++j) {
cout << " " << res[i][j];
if(j == N-1)
cout << endl;
}
}
MPI::Finalize();
return 0;
}
When I run the program with P = 16 and two 4x4 matrices:
>$ mpirun -np 16 ./myprog 4
Matrix A:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
Matrix B:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
Result of A x B:
6366632 0 0 0
-12032 32767 0 0
0 0 -1431597088 10922
1 10922 0 0
Result of A x B:
56 62 68 74
152 174 196 218
248 286 324 362
344 398 452 506
Why is it printing out that first result?
I would really appreciate if someone was willing to help me.
You have undefined behavior / you are corrupting your memory. Let's assume your example with N=4,P=16,p=4. Therefore start=rank.
What do you do when you Scatter? You send 4 elements each to 16 processes. MPI will be assuming A on the root contains 64 elements, but it only contains 16. Further you store them at all ranks in A[start]. I don't even know if that is exactly defined, but it should be equal to A[start][0], which is out of the allocated memory for A when rank >= 4. So you already read and write to invalid memory. The wildly invalid memory accesses continue in the loop and Gather.
Unfortunately, MPI programs can be difficult to debug, especially with respect to memory corruption. There is very valuable info for OpenMPI. Read the entire page! mpirun -np 16 valgrind ... would have told you about the issue.
Some other notable issues:
The C++ bindings of MPI have been deprecated for years. You should
either use the C bindings in C++ or a high level binding such as
Boost.MPI.
Variable-length arrays are not standard C++.
You don't need a Barrier before the Gather.
Make sure your code is not full of unchecked assumptions. Do assert that P is square, if you need it to be, that N is divisible by p, if you need it to be.
Never name two variables P and p.
Now I am struggling as to what I should recommend you in addition to using debugging tools. If you need a fast parallel matrix multiplication - use a library. If you want to write nice high-level code as an exercise - use boost::mpi and some high-level matrix abstraction. If you want to write low-level code as an exercise - use std::vector<>(N*N), build your own 2D-index and think carefully how to index it and how to access the correct chunks of memory.