Hey guys,

I'm struggling with yet another problem. The goal is to run 1000 "draws" of three numbers but the catch is, the three numbers can't be repeating. So, no 4 1 4 or 7 7 7 or 8 1 8 and so on and so forth. Every line of three numbers must have the three numbers be from 1-8.

#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
using namespace std;

int main()
{
    int Yellow = 1; 
    int Blue = 2;
    int Red = 3; 
    int Purple = 4; 
    int Orange = 5; 
    int Green = 6; 
    int Maroon = 7;  
    int Black = 8;
    int tally_total = 1000;
    int tally[tally_total];

    for(int i = 0; i < tally_total; i++)
    {
    tally[i] = (rand()%8)+1;   
    tally[i+1] = (rand()%8)+1;
    tally[i+1] != tally[i];
    
    while(tally[i+1] == tally[i])
    {
    if(tally[i+1] == tally[i])
    {
                  tally[i+1] = (rand()%8)+1;
                  continue;}
    }
    tally[i+2] = (rand()%8)+1;
    tally[i+2] != tally[i] || tally[i+1];
    
    while(tally[i+2] == tally[i])
    {
         if(tally[i+2] == tally[i])
         {
                  tally[i+2] = (rand()%8)+1;
                  continue;
         }
    }
    
    while(tally[i+2] == tally[i+1])
    {
	     if(tally[i+2] == tally[i+1])
	     {
	              tally[i+2] = (rand()%8)+1;
	              continue;
		 }
	}
    
    
    if(tally[i+1] == tally[i])
    cout << "NUMBERS REPEATED";
    if(tally[i+1] == tally[i+2])
    cout << "NUMBERS REPEATED";
    if(tally[i] == tally[i+2])
    cout << "NUMBERS REPEATED";
    
    cout << tally[i] 
         << " " 
         << tally[i+1] 
         << " " 
         << tally[i+2]
         << endl;
    }
     
    getchar();
    getchar();
    return 0;    
}

Dani AI

Generated

Brief diagnosis and a safe fix

The intermittent repeats reported by are almost always caused by two things: (1) undefined behaviour from incorrect indexing when writing three numbers per iteration into a single array sized for one value per iteration, and (2) logic that looks like a check but is actually a no-op (standalone comparison expressions) or uses the wrong boolean combination. correctly spotted a broken boolean expression, and pointed toward the right pattern (regenerate while equal) — the difference is implementing those checks without accidentally stepping outside the array or writing comparisons that do nothing.

What went wrong, concretely

  • Writing multiple values in each loop pass without adjusting the loop index (or without allocating 3 * N storage) can write past the array end and corrupt memory; that produces occasional, non-deterministic bad results.
  • Expressions like a != b by themselves do nothing; they must be used inside a condition.
  • To enforce uniqueness for a new pick you either loop while it equals any previous pick (use OR on equality checks) or require it to be not equal to both (use AND on inequality checks). Mixing those up produces the wrong behavior.

A robust, modern approach
Use sampling without replacement instead of repeated trial-and-error. Example using C++11+:

#include <algorithm>
#include <random>
#include <vector>
#include <iostream>

std::vector<int> pool{1,2,3,4,5,6,7,8};
std::mt19937 rng{std::random_device{}()};

for (int draw = 0; draw < 1000; ++draw) {
    std::shuffle(pool.begin(), pool.end(), rng);
    std::cout << pool[0] << ' ' << pool[1] << ' ' << pool[2] << '\n';
}

This guarantees three distinct numbers per draw and avoids index mistakes. If using C++17, std::sample does the same without shuffling the whole pool.

Quick troubleshooting tips
Compile with warnings enabled, run with AddressSanitizer or Valgrind to catch out-of-bounds writes, and prefer <random> over rand() for better quality. If storing results, allocate storage for three values per draw (or store each triple in its own small vector/struct) so indexing is simple and safe.

Recommended Answers

All 3 Replies

tally[i+2] != tally[i] || tally[i+1] (line 34) is not doing what you want it to do. You need (tally[i+2] !=tally[i]) || (tally[i+2] !=tally[i+1]) .

Have a test condition in your for loop.

In psuedocode :

for i = 0 untill MAX{
pick1 = random number
pick2 = random number
while(pick2 == pick1 ) pick2 = another random number
pick3 = random number
while(pick3 == pick2 or pick3 == pick1) pick3 = another random number
}

First, thanks to both jonsca and firstperson!

I rewrote the code AGAIN and got it to work! Firstperson, your psuedocode was exactly what I needed. Sorry for the long time offline, but my family thinks I'm becoming addicted from CSC haha. I spent about three hours of work to JUST GET the duplicates to go away, and couldn't manage to do it myself. Pathetic, I know. Again, thanks a bunch to both of you! Topic solved!

EDIT: If someone has some time and could PM me, I'd love to know why my original code didn't work fully. Out of 1000 runs, it had 7 repeating numbers per roll. Why was that?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.