Sudoku Blanks - c++ - c++

I have to write a program that takes in a Sudoku square(with all slots filled) and randomly assigns 25 blanks to be filled in. This is what I have so far but because this code has the chance to generate the same position in the array more than once I'm getting a varying number of blanks(17-21). I'm wondering if there is a simple way to get it to output 25 blanks no matter what. My print function inserts a blank if the value is zero at any spot in the array.
void insertBlanks(int square[9][9])
{
srand(time(NULL));
int i = 0;
while(i < 25)
{
int tempOne = rand() % 9;
int tempTwo = rand() % 9;
square[tempOne][tempTwo] = 0;
i = i + 1;
}
}

You should check if a 0 is already there.
if(square[tempOne][tempTwo] != 0)
{
square[tempOne][tempTwo] = 0;
i = i + 1;
}

Related

C++ Function Gives "Not all Control Paths Return A Value" Error

I am working on a function called add(BigDecimals c) which keeps getting an error that not all control paths are returning a value:
BigDecimal BigDecimal::add(BigDecimal c)
{
string fFirst = to_string(this->fraction()); //fraction part of the first number
string fSecond = to_string(c.fraction()); //fraction part of the second number
if (fFirst.length() < fSecond.length()) //fraction part of first/second number
{
string str(this->toString()); //convert fraction to string
for (unsigned int i = 0; i < fFirst.length() - fSecond.length(); i++) //difference between first and second
{
str += "0"; //pad in the 0's
}
this->equals(str); //call the equals function
}
if (fSecond.length() < fFirst.length()) //flip numbers around, second < first
{
string str(this->toString()); //convert fraction to string
for (unsigned int i = 0; i < fSecond.length() - fFirst.length(); i++) //difference between second and first
{
str += "0"; //pad in the 0's
}
this->equals(str); //call the equals function
}
for (unsigned int i = fSecond.length(); i > 0; i++)
{
int carryFlag = 0; //carry flag set to 0
int sum = carryFlag + stoi(this->at(i).toString()) + stoi(c.at(i).toString());
if (sum >= 10) //greater than 10
{
carryFlag = 1;
sum = sum % 10;
}
else //less than 10
{
carryFlag = 0; //set carry flag to 0
}
return BigDecimal(to_string(sum)); //this is the only thing I want to
//return
}
//It wants to return something here, but I am not sure what.
}
I have tried to fix this by replacing if statements with else statements, but nothing really works. I have no idea how to fix this error, so any help is appreciated!
Your logic is flawed (and the error message and the fact you don't know what to do about it is a good indication of that).
Your code will always return on the first iteration of the loop. Clearly what you want to do is accumulate a digit string one digit at a time, but that's not what the code you've written does.
This is something more like what you want. However I think you have other errors to do with the padding of numbers, so this code isn't going to work, but hopefully will give you some idea.
string result = "";
int carryFlag = 0; //carry flag set to 0
for (unsigned int i = fSecond.length(); i > 0; i--)
{
int sum = carryFlag + stoi(this->at(i).toString()) + stoi(c.at(i).toString());
if (sum >= 10) //greater than 10
{
carryFlag = 1;
sum = sum % 10;
}
else //less than 10
{
carryFlag = 0; //set carry flag to 0
}
result = to_string(sum) + result;
}
if (carryflag)
result = "1" + result;
return BigDecimal(result);
Notice the return is only after the loop has finished, and a new variable called result accumulates the digit generated each time round the loop.
Also notice the carryflag variable has been moved outside of the loop. The whole point of the carry is to hold the carry from one iteration of the loop to the next, so it can't be inside the loop. Also if there is a carry left over after all the digits have been added, you need to add a one digit to the beginning of the result.
Also I've changed i++ to i-- in the loop. You are iterating backwards through the strings you are adding so you need i--. It's an improvment but as I said before I still think this loop is wrong.
Clearly you understand how to do long addition, but what you haven't mastered yet is how to translate that into code. You have to think very carefully and precisely about what you are asking the computer to do.

How to find local maximums in data set using C++?

I am using an arduino to read a sensor which stores 256 values into an array. I am trying to find local max's but some values being stored have repeating values to the left and right of itself causing the value to print multiple times. Is there a way to take all true values meaning they are a max value and store them in another array to process and reduce the repeated values to just 1 value...
OR is there a way to send the max values to another array where the repeated values get reduced to just 1? OR
IE:
Array1[] = {1,2,3,4,4,4,3,2,7,8,9,10}
max = 4 at index 3
max = 4 at index 4
max = 4 at index 5
since 4 is a peak point but repeats how can I reduce it so that the array looks like
Array2[] = {1,2,3,4,3,2,7,8,9,10}
max = 4 at index 3
I need the most basic breakdown if possible nothing on an expert level, thanks.
Code from Arduino:
int inp[20] = {24,100,13,155,154,157,156,140,14,175,158,102,169,160,190,100,200,164,143,20};
void setup()
{
Serial.begin(9600); // for debugging
}
void loop()
{
int i;
int count = 0;
for (i = 0; i < 20; i++)
{
Serial.println((String)inp[i]+" index at - "+i);
delay(100);
};
int N = 5; // loc max neighborhood size
for (int i = N-1; i < 19-N; i++)
{
bool loc = false;
for (int j = 1; j < N; j++) // look N-1 back and N-1 ahead
{
if (inp[i] > inp[i-j] && inp[i] > inp[i+j]) loc = true;
}
if (loc == true)
{
Serial.println((String)"max = "inp[i]+" at index "+i);
}
}
Serial.println("----------------------------------");
}
You can detect "local maxima" or peaks in a single loop without the need of copying something into another array. You just have to ignore repeating values, and you just have to keep track if the values considered are currently increasing or decreasing. Each value after which this status switches from increasing to decreasing is then a peak:
int main() {
int Array1[] = {1,2,3,4,4,4,3,2,7,8,9,10};
int prevVal = INT_MIN;
enum {
Ascending,
Descending
} direction = Ascending;
for (int i=0; i<sizeof(Array1)/sizeof(*Array1); i++) {
int curVal = Array1[i];
if (prevVal < curVal) { // (still) ascending?
direction = Ascending;
}
else if (prevVal > curVal) { // (still) descending?
if (direction != Descending) { // starts descending?
cout << "peak at index " << i-1 << ": " << prevVal << endl;
direction = Descending;
}
}
// prevVal == curVal is simply ignored...
prevVal = curVal;
}
}

How do I randomize these numbers?

So my homework assignment is to create a looping function to print only even numbers from 0 – 200. I need to create 100 random and even numbers(only 10 numbers can print per line). I'm having trouble randomizing the numbers. This is what I have so far:
// Loop from 0 to 200
for (i = 2, j = 1; i <= 200; i++, j++)
{
// Print even numbers(divisible by 2)
if (i % 2 == 0)
{
cout << i;
}
// Create new line after printing 10 numbers
if (j == 20)
{
j = 0;
ofs << '\n';
}
}
#include <stdio.h> /* printf, scanf, puts, NULL */
#include <stdlib.h> /* srand, rand */
#include <time.h>
int main()
{
srand (time(NULL));
int even = rand() % 200;
if (even % 2 == 0)
{
cout<<even;
}
}
Here is some quick code that prints 100 even numbers [0..200] in a random order without repeating them:
#define PRIME 7879 /* Some big prime number (>> 100) */
#define NUMS 100 /* Number of values to process */
#define PRINT_GROUP 10 /* Number of values printed on a line */
int main()
{
int number = rand() % NUMS;
int i;
for (i = 0; i < NUMS; i++) {
printf("%d%c", 2*number, (i + 1) % PRINT_GROUP == 0 ? '\n' : ' ');
number = (number + PRIME) % NUMS;
}
return 0;
}
Apart from that, your code is a little off the way.
Here are some things that may be confusing to other coders (.. anyways if you feel comfortable with your style that's really ok)
"for (i = 2, j = 1; i <= 200; i++, j++)" 2 Variables are a little bit wierd,
try to use only one variable. .. Just make it something like this:
int j = 1;
for (i = 2; i <= 200; i++) {
j++;
//Code
if (j == 20) {
j = 0; //etc.
}
}
Beside that "J" looks familliar to "I" so that could confuse others.. try to call it "count", that's pretty standard.

Inconsistent randomization in array

Basically, I have a 6x6 board. I created a function that's supposed to place three X's on random coordinates on the board.
const int size = 6;
char board[6][6] = {0}; //this is actually somewhere else, but I included it here for clarity
char enemies[3] = {'X','X','X'};
void setup(char board[6][6]){
bool valid = false; //sets initial bool value to false
for (int x = 0; x <= 2; ++x){
do{
int a = rand() % size;
int b = rand() % size;
if (board[a][b] == 0){
board[a][b] = enemies[x];
valid = true;
}
}while(!valid); //if the value is false, redo until an empty board space is found
}
(I included srand(time(NULL)) in the main function as well)
It works, but only sometimes. Sometimes it generates 3 randomly placed X's, and sometimes only 2. I want it to generate 3 every single time. I have been over it a million times, trying minor variations and corrections, but I can't seem to figure out what's wrong. I included a condition for it to only place enemies[x] if the board is blank (board[a][b] == 0), and yet it sometimes only places 2 X's for some reason.
After the first X is placed, valid remains true for all subsequent iterations of the for loop, even if a valid square hasn't been found.
I changed the iteration variable to i (using x to mean something other than an ordinal when you're using 2d coordinates is just confusing), and fixed your inner retry loop:
for (int i = 0; i <= 2; ++i) {
// loop until we find a valid coordinate
while(true) {
int a = rand() % size;
int b = rand() % size;
if (board[a][b] == 0){
board[a][b] = enemies[i];
break; // we found one!
}
}
}
You are not resetting the valid flag inside the outer loop. So, once you've placed the first piece, you do not correctly handle duplicates.
for (int x = 0; x <= 2; ++x)
{
valid = false; // <-- you forgot to do this.
do
{
int a = rand() % size;
int b = rand() % size;
if (board[a][b] == 0)
{
board[a][b] = enemies[x];
valid = true;
}
} while(!valid);
}
After each run through the do/while loop you need to reset valid. After the first iteration (when x is 0), valid will be set to true. You never reset it back to false, and so on the next iterations (starting with x being 1), valid will be set to true already. This means that you might select a random coordinate that you've already marked and then proceed to the next x anyway.
That means it's entirely possible that only one square will have been marked, but the odds of this are low (1 in 1,225, if my math is correct).

Generate unique multiple random numbers

I want to generate unique random numbers and add item in function of these random numbers. Here is my code :
The problem is when i verify if the number generated exist in the array with the code results.contains(randomNb) :
int nbRandom = ui->randoomNumberSpinBox->value();
//nbRandom is the number of the random numbers we want
int i = 1;
int results[1000];
while ( i < nbRandom ){
int randomNb = qrand() % ((nbPepoles + 1) - 1) + 1;
if(!results.contains(randomNb)){
//if randomNb generated is not in the array...
ui->resultsListWidget->addItem(pepoles[randomNb]);
results[i] = randomNb;
//We add the new randomNb in the array
i++;
}
}
results is an array. That's a built-in C++ type. It's not a class type and doesn't have methods. So this can't work:
results.contains(randomNb)
You probably want to use a QList instead. Like:
QList<int> results;
Add elements to it with:
results << randomNb;
Also, you have an off-by-one error in the code. You start counting from 1 (i = 1) instead of 0. This will result in missing the last number. You should change the i initialization to:
int i = 0;
With the changes, your code would become:
int nbRandom = ui->randoomNumberSpinBox->value();
//nbRandom is the number of the random numbers we want
int i = 0;
QList<int> results;
while ( i < nbRandom ){
int randomNb = qrand() % ((nbPepoles + 1) - 1) + 1;
if(!results.contains(randomNb)){
//if randomNb generated is not in the array...
ui->resultsListWidget->addItem(pepoles[randomNb]);
results << randomNb;
//We add the new randomNb in the array
i++;
}
}