Output 4 set of 7 ascendant ordered and unique random numbers - c++

I'm having some difficulty figuring out how to solve my issue here, and I thought why not go here and ask you professionals for some help.
The main thing is, I've only been studying C++ for a few weeks in School, and roughly what
I've been going through are if/else, for/while/do loops, arrays and obviously some more basic stuff, so my main problem while trying to solve this is whether or not my knowledge is enough?
Would this be easier solved if I read on about vectors etc?
Now, what I have been successful of doing is sorting the numbers which I solved like this:
Basically what I used is an bubble sort algorithm (I think?)
for(int i=0; i<6; i++)
{
for(int j=0; j<6; j++)
{
if(slump[j]>random[j+1])
{
temp = random[j];
slump[j] = random[j+1];
slump[j+1] = random;
}
}
}
However I can't for the life of me figure out how to prevent duplicates from appearing (there can be duplicates from row to row but not on the same row) when assigning each index from 0-6 a random number.
for(int j=0;j<7;j++)
{
random[j] = rand()%40+1;
}
I hope I've made myself somewhat clear, as English isn't my native language, please do tell me if I need to clarify anything. And I do hope I can find some help on how to solve this, with a not too complex solution here.

The sorting procedure will not help you to prevent duplicates, so it must be resolved before.
First you ensure that there are no duplicated numbers. When you get all the numbers you need.
To ensure that there are no random numbers, two options:
After each number is generated, check against the numbers already obtained. If it is repeated, discard it and get a new random number.
Since you want 7 numbers in a 40 wide range, just use it as an order. The first number is picked between 0-39, the second number between 0-38, and so on. Already used numbers are skipped (so, a random sequence of 3-5-2-4 means the number sequence 3-6-2-7)

Umm, it shouldn't be too hard to check for duplicates.
You could try the following for instance:
for (int i = 0; i < 7; i++)
{
random[i] = rand%40 + 1;
}
for (int i = 0; i < 7; i++)
{
for (int j = 1; j < 7; j++)
{
if(random[i] == random[j])
{
random[i] = rand%40 + 1;
i = i -1;
break;
}
}
}
I'm pretty sure that should be a profecceint check for whether or not a number has been repeated in random[]. Also, even though vectors are more fun and somewhat easier to use they will not make this operation easier.
Hope it helps. =)

Related

Comparing indexes in arrays/vectors

I just completed a project through Codecademy, and I couldn't for the life of me figure it out. I went and looked at the example solution and it contained code that I didn't even know you could do and I cannot figure out how it works.
There is a nested for loop, and the user takes advantage of adding the indexes together?? Or is comparing them?? I've just never seen it done, to be quite honest and I have looked for an explanation of what exactly is happening and I can't find one.
`
for (int i = 0; i < text.size(); ++i) {
int match = 0;
for (int j = 0; j < word.size(); ++j) {
if (text[i+j] == word[j]) {
++match;
}
}
`
The project was a C++ program where you had to bleep a word out of any phrase that was input into the program. I just don't understand what "text[i+j]" accomplishes? How do you add two indexes together in a for loop?? Does it add?? Does it compare?? But comparison doesn't make much sense to me either??
Here is a link to the github repository as well, so you can see the entire program: https://github.com/Codecademy/learn-cpp/tree/master/8-references-and-pointers/bleep
Since you're learning, the easiest way to figure this out is to write out exactly what is happening. Take text=="Hello, World and word=="World", and work out on paper how this code runs. For what values of i and j will match be incremented?

How to choose a random number excluding those which were previously chosen? [duplicate]

I'd like to make a number generator that does not repeat the number it has given out
already (C++).
All I know is:
int randomgenerator(){
int random;
srand(time(0));
random = rand()%11;
return(random);
} // Added this on edition
That function gives me redundant numbers.
I'm trying to create a questionnaire program that gives out 10 questions in a random order and I don't want any of the questions to reappear.
Does anyone know the syntax?
What I would do:
Generate a vector of length N and fill it with values 1,2,...N.
Use std::random_shuffle.
If you have say 30 elements and only want 10, use the first 10 out the vector.
EDIT: I have no idea how the questions are being stored, so.. :)
I am assuming the questions are being stored in a vector or somesuch with random access. Now I have generated 10 random numbers which don't repeat: 7, 4, 12, 17, 1, 13, 9, 2, 3, 10.
I would use those as indices for the vector of questions:
std::vector<std::string> questions;
//fill with questions
for(int i = 0; i < number_of_questions; i++)
{
send_question_and_get_answer(questions[i]);
}
You are trying to solve the problem "the wrong way".
Try this instead (supposing you have a vector<int> with question ids, but the same idea will work with whatever you have):
Get a random R from 0 to N-1 where N is the number of questions in the container
Add question R to another collection of "selected" questions
If the "selected questions" collection has enough items, you 're done
Remove question R from your original container (now N has decreased by 1)
Go to 1
Sounds like you essentially want to shuffle a deck of cards (in this case, the "cards" being the questions, or question numbers).
In C++, I would do:
#include <vector>
#include <algorithms>
std::vector<int> question_numbers;
for (unsigned int i = 0; i < 10; ++i)
question_numbers.push_back(i+1);
std::random_shuffle(question_numbers.begin(), question_numbers.end());
// now dole out the questions based on the shuffled numbers
You do not have to hand out all of the questions, any more than you have to deal out a whole deck of cards every time you play a game. You can, of course, but there's no such requirement.
Create a vector of 10 elements (numbers 1-10), then shuffle it, with std::random_shuffle. Then just iterate through it.
Should look more like this: (Note: does not solve your original problem).
int randomgenerator(){
int random;
// I know this looks re-dunand compared to %11
// But the bottom bits of rand() are less random than the top
// bits do you get a better distribution like this.
random = rand() / (RAND_MAX / 11);
return random;
}
int main()
{
// srand() goes here.
srand(time(0));
while(true)
{
std::cout << randomgenerator() << "\n";
}
}
A better way to solve the original problem is to pre-generate the numbers so you know that each number will appear only once. Then shuffle the order randomly.
int main()
{
int data[] = { 0,1,2,3,4,5,6,7,8,9,10,11};
int size = sizeof(data)/sizeof(data[0]);
std::random_shuffle(data, data + size);
for(int loop = 0; loop < size; ++loop)
{
std::cout << data[loop] << "\n";
}
}
Why not use some STL to perform the checks for you? The idea:
Create an (initially empty) set of 10 integers that will be the indices of the random questions (they will be distinct as a set forbids duplicate items). Keep pushing random numbers in [0, num_of_questions-1] in there until it grows to a size of 10 (duplicates will get rejected automatically). When you have that set ready, iterate over it and output the questions of the corresponding indexes:
std::vector<std::string> questions = /* I am assuming questions are stored in here */
std::set<int> random_indexes;
/* loop here until you get 10 distinct integers */
while (random_indexes.size() < 10) random_indexes.insert(rand() % questions.size());
for (auto index: random_indexes){
std::cout << questions[index] <<std::endl;
}
I may be missing something, but it seems to me the answers that use shuffling of either questions or indexes perform more computations or use an unnecessary memory overhead.
//non repeating random number generator
for (int derepeater = 0; derepeater < arraySize; derepeater++)
{
for (int j = 0; j < arraySize; j++)
{
for (int i = arraySize; i > 0; i--)
{
if (Compare[j] == Compare[i] && j != i)
{
Compare[j] = rand() % upperlimit + 1;
}
}
}
}

ARRAYS DEBUGGING incorrect outputs, complex algorithm

I made this algorithm, i was debugging it to see why it wasnt working, but then i started getting weird stuff while printing arrays at the end of each cycle to see where the problem first occurred.
At a first glance, it seemed my while cycles didn't take into consideration the last array value, but i dunno...
all info about algorithm and everything is in the source.
What i'd like to understand is, primarily, the answer to this question:
Why does the output change sometimes?? If i run the program, 60-70% of the time i get answer 14 (which should be wrong), but some other times i get weird stuff as the result...why??
how can i debug the code if i keep getting different results....plus, if i compile for release and not debug (running codeblocks under latest gcc available in debian sid here), i get most of the times 9 as result.
CODE:
#include <iostream>
#include <vector>
/*void print_array
{
std::cout<<" ( ";
for (int i = 0; i < n; i++) { std::cout<<array[i]<<" "; }
std::cout<<")"<<std::endl;
}*/
///this algorithm must take an array of elements and return the maximum achievable sum
///within any of the sub-arrays (or sub-segments) of the array (the sum must be composed of adjacent numbers within the array)
///it will squeeze the array ...(...positive numbers...)(...negative numbers...)(...positive numbers...)...
///into ...(positive number)(negative number)(positive number)...
///then it will 'remove' any negative numbers in case it would be convienent so that the sum between 2 positive numbers
///separated by 1 negative number would result in the highest achievable number, like this:
// -- (3,-4,4) if u do 'remove' the negative number in order to unite the positive ones, i will get 3-4+4=3. So it would
// be better not to remove the negative number, and let 4 be the highest number achievable, without any sums
// -- (3,-1,4) in this case removing -1 will result in 3-1+4=6, 6 is bigger than both 3 and 4, so it would be convienent to remove the
// negative number and sum all of the three up into one number
///so what this step does is shrink the array furthermore if it is possible to 'remove' any negatives in a smart way
///i also make it reiterate for as long as there is no more shrinking available, because if you think about it not always
///can the pc know if, after a shrinking has occured, there are more shrinkings to be done
///then, lastly, it will calculate which of the positive numbers left is highest, and it will choose that as remaining maximum sum :)
///expected result for the array of input, s[], would be (i think), 7
int main() {
const int n=4;
int s[n+1]={3,-2,4,-4,6};
int k[n+1]={0};
///PRINT ARRAY, FOR DEBUG
std::cout<<" ( ";
for (int i = 0; i <= n; i++) { std::cout<<k[i]<<" "; }
std::cout<<")"<<std::endl;
int i=0, j=0;
// step 1: compress negative and postive subsegments of array s[] into single numbers within array k[]
/*while (i<=n)
{
while (s[i]>=0)
{
k[j]+=s[i]; ++i;
}
++j;
while (s[i]<0)
{
k[j]+=s[i]; ++i;
}
++j;
}*/
while (i<=n)
{
while (s[i]>=0)
{
if (i>n) break;
k[j]+=s[i]; ++i;
}
++j;
while (s[i]<0)
{
if (i>n) break;
k[j]+=s[i]; ++i;
}
++j;
}
std::cout<<"STEP 1 : ";
///PRINT ARRAY, FOR DEBUG
std::cout<<" ( ";
for (int i = 0; i <= n; i++) { std::cout<<k[i]<<" "; }
std::cout<<")"<<std::endl;
j=0;
// step 2: remove negative numbers when handy
std::cout<<"checked WRONG! "<<unsigned(k[3])<<std::endl;
int p=1;
while (p!=0)
{
p=0;
while (j<=n)
{
std::cout<<"checked right! "<<unsigned(k[j+1])<<std::endl;
if (k[j]<=0) { ++j; continue;}
if ( k[j]>unsigned(k[j+1]) && k[j+2]>unsigned(k[j+1]) )
{
std::cout<<"checked right!"<<std::endl;
k[j+2]=k[j]+k[j+1]+k[j+2];
k[j]=0; k[j+1]=0;
++p;
}
j+=2;
}
}
std::cout<<"STEP 2 : ";
///PRINT ARRAY, FOR DEBUG
std::cout<<" ( ";
for (int i = 0; i <= n; i++) { std::cout<<k[i]<<" "; }
std::cout<<")"<<std::endl;
j=0; i=0; //i will now use "i" and "p" variables for completely different purposes, as not to waste memory
// i will be final value that algorithm needed to find
// p will be a value to put within i if it is the biggest number found yet, it will keep changing as i go through the array....
// step 3: check which positive number is bigger: IT IS THE MAX ACHIEVABLE SUM!!
while (j<=n)
{
if(k[j]<=0) { ++j; continue; }
p=k[j]; if (p>i) { std::swap(p,i); }
j+=2;
}
std::cout<<std::endl<<"MAX ACHIEVABLE SUM WITHIN SUBSEGMENTS OF ARRAY : "<<i<<std::endl;
return 0;
}
might there be problems because im not using vectors??
Thanks for your help!
EDIT: i found both my algorithm bugs!
one is the one mentioned by user m24p, found in step 1 of the algorithm, which i fixed with a kinda-ugly get-around which ill get to cleaning up later...
the other is found in step2. it seems that in the while expression check, where i check something against unsigned values of the array, what is really checked is that something agains unsigned values of some weird numbers.
i tested it, with simple cout output:
IF i do unsigned(k[anyindexofk]) and the value contained in that spot is a positive number, i get the positive number of course which is unsigned
IF that number is negative though, the value won't be simply unsigned, but look very different, like i stepped over the array or something...i get this number "4294967292" when im instead expecting -2 to return as 2 or -4 to be 4.
(that number is for -4, -2 gives 4294967294)
I edited the sources with my new stuff, thanks for the help!
EDIT 2: nvm i resolved with std::abs() using cmath libs of c++
would there have been any other ways without using abs?
In your code, you have:
while (s[i]>=0)
{
k[j]+=s[i]; ++i;
}
Where s is initialized like so
int s[n+1]={3,-2,4,-4,6};
This is one obvious bug. Your while loop will overstep the array and hit garbage data that may or may not be zeroed out. Nothing stops i from being bigger than n+1. Clean up your code so that you don't overstep arrays, and then try debugging it. Also, your question is needs to be much more specific for me to feel comfortable answering your question, but fixing bugs like the one I pointed out should make it easier to stop running into inconsistent, undefined behavior and start focusing on your algorithm. I would love to answer the question but I just can't parse what you're specifically asking or what's going wrong.

How to determine the number of array 100 are not equal to each other

I am coding a Sudoku program. I found the number in the array determine whether duplicate each other is hard.
Now I have an array: int streamNum[SIZE]
if SIZE=3,I can handle this problem like:if(streamNum[0]!=streamNum[1])...
if SIZE=100,I think that I need a better solution, is there any standard practice?
There are a couple of different ways to do this, I suppose the easiest is to write two loops
bool has_duplicate = false;
for (int i = 0; i < SIZE && !has_duplicate; ++i)
for (int j = i + 1; j < SIZE && !has_duplicate; ++j)
if (streamNum[i] == streamNum[j])
has_duplicate = true;
if (has_duplicate)
{
...
}
else
{
...
}
The first loop goes through each element in the array, the second loop checks if there is a duplicate in the remaining elements of the array (that's why it starts at i + 1). Both loops quit as soon as you find a duplicate (that's what && !has_duplicate does).
This is not the most efficient way, more efficient would be to sort the array before looking for duplicates but that would modify the contents of the array at the same time.
I hope I've understand your requirements well enough.
for(int i=0;i<size;i++){
for(int j=i+1;j<size;j++){
if(streamNUM[i]==streamNUM[j]){
...........
}
}
}
I assume that u need whether there is duplication or not this may be helpful
If not comment
It's a little unclear what exactly you're looking to do here but I'm assuming as it's sudoku you're only interested in storing numbers 1-9?
If so to test for a duplicate you could iterate through the source array and use a second array (with 9 elements - I've called it flag) to hold a flag showing whether each number has been used or not.
So.. something like:
for (loop=0;loop<size;loop++) {
if (flag[streamNum[loop]]==true) {
//duplicate - do something & break this loop
break;
}
else {
flag[streamNum[loop]=true;
}
}
Here's how I'd test against Sudoku rules - it checks horizontal, vertical and 3x3 block using the idea above but here 3 different flag arrays for the 3 rules. This assumes your standard grid is held in an 81-element array. You can easily adapt this to cater for partially-completed grids..
for (loop=0;loop<9;loop++) {
flagH=[];
flagV=[];
flagS=[];
for (loop2=0;loop2<9;loop2++) {
//horizontal
if(flagH[streamNum[(loop*9)+loop2]]==true) {
duplicate
else {
flagH[streamNum[(loop*9)+loop2]]=true);
}
//column test
if(flagV[streamNum[loop+(loop2*9)]]==true) {
..same idea as above
//3x3 sub section test
basecell = (loop%3)*3+Math.floor(loop/3)*27; //topleft corner of 3x3 square
cell = basecell+(loop2%3+(Math.floor(loop2/3)*9));
if(flagS[streamNum[cell]]==true) {
..same idea as before..
}
}

How do I count how often each value occurs in a vector?

I have simulated 10 die rolls and stored the numbers in a single vector called data. I need to sort the 10 numbers either in order, or in a way which lets my program know how many of each die face there is. A friend suggested I use an array which steps through the 10 numbers and adds a digit to one of the six columns depending on which die face it is, but I'm unsure of how to do this.
void Game::sort_hands()
{
vector<int> data;
for(int i = 0; i < player.hand.size(); ++i){
data.push_back(player.hand[i]);
data.push_back(opponent.oppHand[i]);
}
for(int i = 0; i < data.size(); ++i){
cout<<data[i]<<" ";
}
}
Well if you are looking for someone to give you answers to your homework, i would say this is the wrong place for that, but we can point you in the right direction. There are many common and easy to implement sorting algorithms, but be aware that the overhead associated with many sorting algorithms may not be worth it considering the size of your data set. Look into algorithms, as well as understand the capabilities of the data structure you are using, the std::vector.