Sudoku solving matrix, while statement gives an infinite loop - c++

This code should produce a solved sudoku matrix, however the while statement puts it in an infinite loop. Removing the while statement gives me a matrix with some values still 99 or 0. And i can't generate 9 random numbers uniquely one by one.
IF YOU WANT TO RUN AND CHECK THE CODE, REMOVE THE WHILE STATEMENT.
int a[9][9];
int b[9][9];
int inputvalue(int x, int y, int value) //checks horizontally, vertically and 3*3matrix for conflicts
{
int i, j;
for (i = 0; i < 9; i++)
{
if (value == a[x][i] || value == a[i][y])
return 0;
}
for (i = (x / 3) * 3; i <= ((x / 3) * 3) + 2; i++)
{
for (j = (y / 3) * 3; j <= ((y / 3) * 3) + 2; j++)
if (b[i][j] == value)
return 0;
}
return value;
}
int main()
{
int i, j, k;
unsigned int s;
cout << "sudoku\n";
time_t t;
s = (unsigned) time(&t);
srand(s);
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
a[i][j] = 99;
}
for (i = 0; i < 9; i++)
{
for (j = 1; j <= 9; j++)//j is basically the value being given to cells in the matrix while k assigns the column no.
while(a[i][k]==99||a[i][k]==0)
{
k = rand() % 9;
a[i][k] = inputvalue(i, k, j);
}
}
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
getch();
}

You are using assignment =, instead of equality == here:
while(a[i][k]=99||a[i][k]=0)
^ ^
this should be:
while(a[i][k]==99||a[i][k]==0)
a[i][k]=99 will always evaluate to true since 99 is non-zero, although your original code does not compile for me under gcc as it is, so I suspect the code you are running either has some parenthesizes or is slightly different.
Also using k in the while loop before it is initialized is undefined behavior and it is unclear that your termination logic makes sense for a k that is constantly changing for each loop iteration.
Another source of the infinite loop is inputvalue which seems to get stuck returning 0 in some instances, so you need to tweak that a bit to prevent infinite loops.
Also, srand(time(NULL)); is a more common way to initialize the pseudo-random number generator

Related

When I change array to vector, the program is abnormal

When I use an array, the following code works well. I tried to replace array with std::vector, but found that procedures often appear abnormalities, need to run more times. Anything I missed? I am using g++ 10.3.
#include <iostream>
#include <vector>
int main() {
int n = 3;
for (int k = 1; k <= 4; ++k) {
// int *A = new int[k]();
std::vector<int> A(k, 0);
int i = 0;
for (; i >= 0; A[i]++) {
for (int j = 0; j < k; ++j) {
std::cout << A[j] << " ";
}
std::cout << "\n";
for (i = k - 1; i >= 0 && A[i] == n - 1; i--)
A[i] = 0;
}
}
return 0;
}
In this for loop in its third part
for (; i >= 0; A[i]++) {
^^^^^^
the variable i can be equal to -1 after the inner loop
for (i = k - 1; i >= 0 && A[i] == n - 1; i--)
where the same variable i is used (for example when k is equal to 1).
So it is unimportant whether you are using a vector or an array. The program has undefined behavior.

Counting Sort in C++

I am trying to implement the Counting Sort in C++ without creating a function. This is the code that I've written so far, but the program doesn't return me any values. It doesn't give me any errors either. Therefore, what is wrong?
#include <iostream>
using namespace std;
int main()
{
int A[100], B[100], C[100], i, j, k = 0, n;
cin >> n;
for (i = 0; i < n; ++i)
{
cin >> A[i];
}
for (i = 0; i < n; ++i)
{
if (A[i] > k)
{
k = A[i];
}
}
for (i = 0; i < k + 1; ++i)
{
C[i] = 0;
}
for (j = 0; j < n; ++j)
{
C[A[j]]++;
}
for (i = 0; i < k; ++i)
{
C[i] += C[i - 1];
}
for (j = n; j > 0; --j)
{
B[C[A[j]]] = A[j];
C[A[j]] -= 1;
}
for (i = 0; i < n; ++i)
{
cout << B[i] << " ";
}
return 0;
}
It looks like you're on the right track. You take input into A, find the largest value you'll be dealing with and then make sure you zero out that many values in your C array. But that's when things start to go wrong. You then do:
for (i = 0; i < k; ++i)
{
C[i] += C[i - 1];
}
for (j = n; j > 0; --j)
{
B[C[A[j]]] = A[j];
C[A[j]] -= 1;
}
That first loop will always go out of bounds on the first iteration (C[i-1] when i=0 will be undefined behavior), but even if it didn't I'm not sure what you have in mind here. Or in the loop after that for that matter.
Instead, if I were you, I'd create an indx variable to keep track of which index I'm next going to insert a number to (how many numbers I've inserted so far), and then I'd loop over C and for each value in C, I'd loop that many times and insert that many values of that index. My explanation may sound a little wordy, but that'd look like:
int indx = 0;
for(int x = 0; x <= k; x++) {
for(int y = 0; y < C[x]; y++) {
B[indx++] = x;
}
}
If you replace the two loops above with this one, then everything should work as expected.
See a live example here: ideone

C ignoring incrementation

I tried this but my compiler(Visual Studio 2013) keeps messing up things.
I have a 9 by 9 matrix indexed from 1. It is 0 at the beginig. And starting from element 1:1 I start incrementing the value in the matrix or incrementing x,y, basically moving to the next matrix element.
However, the program ignores my incrementation and the fact that x,y are initially set to 1.
Also it ignores a function call.
Code is commented below.
I am sure this is the source I am compiling!
Restarted laptop and Visual Studio but still doesn't work.
Opened new project, same thing.
Thanks in advance.
#include<stdio.h>
#include<stdlib.h>
unsigned int Matrix[10][10], x, y;
// Ignore this..
int checkLine()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[k][1] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[k][i] == Matrix[k][j] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkColumn()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[1][k] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[i][k] == Matrix[j][k] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkSquare()
{
unsigned int i, j, k,l,m,n;
for (m = 1; m <= 7; m = m + 3)
for (n = 1; n <= 7; n = n + 3)
for (k = m; k <= m + 2; k++)
for (l = n; l <= n + 2; l++)
for (i = m; i <= m + 2; i++)
for (j = n; j <= n + 2; j++)
if (Matrix[k][l] == Matrix[i][j] && !(k==i && l==j))
return 0;
return 1;
}
void increment()
{
if (y == 9)
{
x++;
y = 1;
}
else y++;
}
void decrement()
{
if (y == 1)
{
x--;
y = 9;
}
else
y--;
}
void print_Matrix(){
unsigned int i, j;
for (i = 1; i <= 9; i++){
for (j = 1; j <= 9; j++)
printf("%u ", Matrix[i][j]);
printf("\n");
}
}
//
// MAIN. PROBLEM BELOW
//**
void main()
{
unsigned int i, j;
for (i = 1; i <= 9;i++)
for (j = 1; j <= 9; j++)
Matrix[i][j] = 0;
print_Matrix(); // Function call is ignored here. Don't know why.***
x = 1;
y = 1;
// X and Y are OBVIOUSLY 1***
while (x < 10) //Condition OBVIOUSLY true***
{
printf("%u, %u", x, y); //Keeps printing 0,3 and eventually 0,2***
printf("\n");
Matrix[x][y]++; //Incrementation...***
print_Matrix(); // Always prints a blank Matrix consisting of only 0's***
if (checkLine() && checkColumn() && checkSquare())
{
increment();
}
if (Matrix[x][y] == 10){
Matrix[x][y] = 0;
decrement();
}
}
print_Matrix();
}
You feel that the increment is ignored because the checkSquare function is buggy. It never returned 1 and hence the increment function was never called.
What happens is that you're incrementing the position marked by x and y, that's position [1][1]. Until it reaches 10 nothing interesting happens, you can actually see the top left corner of the matrix increasign to 10, but then the condition to decrement becomes true and you decrement.
See for yourself (prints),
while (x < 10) //Condition OBVIOUSLY true***
{
printf("%u, %u", x, y); //Keeps printing 0,3 and eventually 0,2***
printf("\n");
Matrix[x][y]++; //Incrementation...***
print_Matrix(); // Always prints a blank Matrix consisting of only 0's***
if (checkLine() && checkColumn() && checkSquare())
{
increment();
}
if (Matrix[x][y] == 10){
Matrix[x][y] = 0;
decrement();
}
printf( "Enter to continue\n" );
getchar();
}
It turns Y = 9, X = 0 and the [1][1] position becomes 0, so you see only zeros because you're not printing the zero indexes.
This process repeats until Y = 1 and X = 0, you increase the position until 10 so that the decrement works again.
When Y = 1, X = 0 and position [0][1] is 10, the decrement call will do x--. Since X is an unsigned int, it will underflow and become 4.2 billion something, which is greater than 10 and the loop ends.
What are you trying to achieve here?
Edit: Something even more amazing happens when you make x and y ints instead of unsigned ints.
Instead of x underflowing it will become -1. Matrix[-1][9]++ strangely increased x by 1 when I ran the code, so x went back to 0. Which means the program loops forever at this point.
The increment function was never called.
It shows matrix and increment when tested online, here are results
1) for C compiler
http://ideone.com/KRLO8w
#include<stdio.h>
#include<stdlib.h>
unsigned int Matrix[10][10], x, y;
// Ignore this..
int checkLine()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[k][1] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[k][i] == Matrix[k][j] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkColumn()
{
unsigned int i, j, k;
for (k = 1; k <= 9; k++){
if (Matrix[1][k] == 0) break;
for (i = 1; i <= 9; i++)
for (j = 1; j <= 9; j++)
if (Matrix[i][k] == Matrix[j][k] && i!=j)
return 0;
}
return 1;
}
//Ignore this..
int checkSquare()
{
unsigned int i, j, k,l,m,n;
for (m = 1; m <= 7; m = m + 3)
for (n = 1; n <= 7; n = n + 3)
for (k = m; k <= m + 2; k++)
for (l = n; l <= n + 2; l++)
for (i = m; i <= m + 2; i++)
for (j = n; j <= n + 2; j++)
if (Matrix[k][l] == Matrix[i][j] && !(k==i && l==j))
return 0;
return 1;
}
void increment()
{
if (y == 9)
{
x++;
y = 1;
}
else y++;
}
void decrement()
{
if (y == 1)
{
x--;
y = 9;
}
else
y--;
}
void print_Matrix(){
unsigned int i, j;
for (i = 1; i <= 9; i++){
for (j = 1; j <= 9; j++)
printf("%u ", Matrix[i][j]);
printf("\n");
}
}
//
// MAIN. PROBLEM BELOW
//**
void main()
{
unsigned int i, j;
for (i = 1; i <= 9;i++)
for (j = 1; j <= 9; j++)
Matrix[i][j] = 0;
print_Matrix(); // Function call is ignored here. Don't know why.***
x = 1;
y = 1;
// X and Y are OBVIOUSLY 1***
while (x < 10) //Condition OBVIOUSLY true***
{
printf("%u, %u", x, y); //Keeps printing 0,3 and eventually 0,2***
printf("\n");
Matrix[x][y]++; //Incrementation...***
print_Matrix(); // Always prints a blank Matrix consisting of only 0's***
if (checkLine() && checkColumn() && checkSquare())
{
increment();
}
if (Matrix[x][y] == 10){
Matrix[x][y] = 0;
decrement();
}
}
print_Matrix();
}
2) for c++ compiler C++ 4.9.2 (changed return type of main to int)
http://ideone.com/Ey5nG1
In your image starting value of 0, 3 is due to buffer limit of command prompt. As the program never ends, so it terminates abruptly and latest few bytes are stored in buffer and is only shown that much. To see complete output redirect it to a file and open it.
Your output is a bit confusing since the output of the line
printf("%u, %u", x, y);
runs into the output of
print_Matrix();
By adding a newline to the output of the first line, i.e. by using
printf("%u, %u\n", x, y);
you will notice that at some point x gets decremented to 0 and never gets incremented again. Since you never print Matrix[0][y], you never see the non-zero values.
In addition to the change to above printf, if you change print_Matrix to:
void print_Matrix(){
unsigned int i, j;
for (i = 0; i <= 9; i++){
// ^^^ Use 0 instead of 1
for (j = 0; j <= 9; j++)
// ^^^ Use 0 instead of 1
printf("%u ", Matrix[i][j]);
printf("\n");
}
}
you will see the non-zero values.
See working code at http://ideone.com/HlQ4xp.

SIGSEGV(signal 11) 'segmentation fault' in FCTRL2 codechef

I am facing SIGSEGV error on submitting solution for codechef small factorial problem code FCTRL2 though the code works fine on ideone
coding language C++ 4.3.2
Example
Sample input:
4
1
2
5
3
Sample output:
1
2
120
6
#include <iostream>
using namespace std;
void fact(int n) {
int m = 1, a[200];
for (int j = 0; j < 200; j++) {
a[j] = 0;
}
a[0] = 1;
for (int i = 1; i <= n; i++) {
int temp = 0;
for (int j = 0; j < m; j++) {
a[j] = (a[j] * i) + temp;
temp = a[j] / 10;
a[j] %= 10;
if (temp > 0) {
m++;
}
}
}
if (a[m - 1] == 0) {
m -= 1;
}
for (int l = m - 1; l >= 0; l--) {
cout << a[l];
}
}
int main() {
int i;
cin >> i;
while (i--) {
int n;
cin >> n;
fact(n);
cout << endl;
}
return 0;
}
Caveat I'm not going to just fix up your code for you straight up, but I will highlight where it's going wrong and why you get the seg fault.
Your problem is with your implementation of how you're trying to handle the digit by digit multiplication - specifically with what happens to your m value. Test it out by outputting m each time it's incremented - you'll find it's incrementing more often than you intend. You're right to realise you need to use an approach to get to 158 digits and your basic concept could be made to work.
The first clue is by testing with n = 6 when you get a leading 0 that you shouldn't even though you try to get rid of that problem with the if block that contains m-=1
Try with n = 25 and you will see a lot of leading zeros.
Any value greater than this will fail with a Segmentation error. The Seg fault is because, with this error, you try to set values of the array a beyond the max index (as m gets greater than 200)
N.B. Your assertion that the code works on Ideone.com is only true up to a point - it will fail with n > 25.
(Erased code computing a factorial using int)
The problem in your code is that you increment m each time temp is not 0 for each digit multiplication. You may then get a SIGSEGV when computing big factorials because m becomes too big. You probably saw it because 0 shows up in front of your result. I guess this is why you added the
if (a[m - 1] == 0) {
m -= 1;
}
You should only increment m when the inside loop is finished and term is not null. Once fixed you can get rid of the above code.
void fact(int n) {
int m = 1, a[200];
for (int j = 0; j < 200; j++) {
a[j] = 0;
}
a[0] = 1;
for (int i = 1; i <= n; i++) {
int temp = 0;
for (int j = 0; j < m; j++) {
a[j] = (a[j] * i) + temp;
temp = a[j] / 10;
a[j] %= 10;
}
// if (temp > 0) {
// a[m++] = temp;
// }
while (temp > 0)
{
a[m++] = temp%10;
temp /= 10;
}
}
for (int l = m - 1; l >= 0; l--) {
cout << a[l];
}
}

Collatz sequence algorithm not working right

For some reason, this always returns value 1. The point of this is to find the starting number (1-1,000,000) that loops the most amount of times (until j = 1). j will always end up being 1 eventually (collatz theory), I divide j by 2 if it's even, or multiple by 3 and add 1 if it's odd.
#include <iostream>
using namespace std;
int collatz() {
int counter = 0;
int holder = 0;
for (int i = 999999; i > 1; i--){ // loops 999,999 times
for (int j = i; j != 1; counter++) { // loops until j = 1, records amount of loops
if (j % 2 == 0) { // if j is even, divide by 2, +1 to counter
j = j / 2;
} else {
j = (j*3) + 1; // if j is odd, multiply by 3 and add 1, +1 to counter
}
}
if (holder < counter){ // records highest number of loops
holder = counter;
counter = 0;
} else {
counter = 0;
}
}
return holder;
}
int main()
{
cout << collatz << endl;
return 0;
}
You're not calling your function, you're printing out the function pointer (which is converted to the bool value true (i.e. 1)).
First, use unsigned int or unsigned long long as the variable type of j to increase the arithmetic range.
Then, in the loop, check for overflow.
while (j!=1) {
counter++;
if (j % 2 == 0) {
j >>= 1;
} else {
unsigned int j2 = j;
j = (j*3) + 1;
if (j2 > j) {
return -1; // or surround this with try/catch/throw exception
}
}
}
With int i; the counter will overflow at i==113383;
and with unsigned int i; at 159487. If these are not checked, there's a possibility of infinite loop.