Using Recursion/Backtracking to create and solve a sudoku puzzle - c++

For my computer class, my teacher wants us to use recursion or backtracking to create and solve an nXn size sudoku puzzle. The puzzle has to be dynamically allocated and the only rules for the puzzle is that there can be no repetition in any rows or columns. Diagonals and smaller sub-squares can have repeats. Here is what I have written so far.
#include<iostream>
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
void fill_puzzle(int **array, int size);
void delete_puzzle(int array, int size);
bool check_filled(int **array, int size);
bool check_correct(int **array, int size){
int temp=0;
for(int i=0; i<size; i++){
for (int j=0; j<size; j++){
for (int k=0;k<size;k++){
if (array[i][k]==array[i][j])
return false;
else
return true;
}
}
}
}
void fill_puzzle(int **array, int size){
srand(time(NULL));
int random_number;
random_number=(rand()%size);
while(check_correct(array,size)==false)
for(int i=0; i<size; i++){
for (int j=0; j<size; j++){
array[i][j]=random_number;
if (check_correct(array, size) ==false)
fill_puzzle(array, size);
else
cout << array[i][j];
}
}
}
void delete_puzzle(int **array, int size){
for (int i=0; i<size; i++){
delete [] array[i];
}
delete []array;
}
int main(){
int size=0;
int **array;
cout << "Hello, what size puzzle would you like to create? Please type 1 number. Example: 3 would make a 3x3 sudoku puzzle."<<endl;
cin >> size;
if (size <= 0){
cout << "The size you have chosen will not work, please choose a number greater than 0." << endl;
cin >> size;
for (int i=0; i<size; i++){
array=new int*[size];
array[size]=new int [size];
}
}
else {
for (int i=0; i<size; i++){
array=new int*[size];
array[size]=new int [size];
}
fill_puzzle(array,size);
delete_puzzle(array, size);
}
return 0;
}
When I try to compile, I get a segmentation error, and using GDB it says that the error occurs in check_correct in the line with if (array[i][k]==array[i][j]). Thanks in advance.

As I can see so far, the code for allocating memory for the 2D array is not correct and the segmentation fault is caused by accessing illegal memory since you didn't allocate properly.
for (int i=0; i<size; i++){
array=new int*[size]; // move it out of loop
array[size]=new int [size]; //array[size]?!
try this:
array = new int*[size];
for(int i = 0; i < size; ++i)
array[i] = new int[size];
There are others problems(fill_puzzle() stuck in an infinite recursion, it leads your stack grow bigger and bigger, until you get a segmentation fault) in your sudoku solver, use a debugger to solve it.

Related

Why is this recursive selection sort not working

I tried to run the code but it just gets stuck. NO error no warning nothing.Is there a better way to write a recursive selection sort?
#include <iostream>
using namespace std;
void scan(int *arr, int size){
for(int i = 0; i < size; i++){
cin >> arr[i];
}
}
void print(int *arr, int size){
for(int i = 0; i < size; i++){
cout << arr[i] << " ";
}
cout << "\n";
}
void swap(int *p1, int *p2){
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
void insertion(int *arr, int size){
if(size <= 1)return;
int i, max = size - 1;
for(int i = 0; i < size; i++){
if(arr[i] > arr[max])max = i;
}
swap(&arr[max], &arr[i]);
insertion(arr, size - 1);
}
int main(){
int *arr;
int size;
cout << "Enter the size of the array - ";
cin >> size;
arr = (int*)malloc(size*sizeof(int));
cout << "Enter the elements of the array - ";
scan(arr, size);
print(arr, size);
insertion(arr, size);
print(arr, size);
}
I feel like there is something wrong with the base case of the recursion. How do you generally solve these types of problems.
There was 1 small problem in your code. When you call the swap function in the insertion function you have to call it with &arr[max] and &arr[size-1], you can also use i-1, as the value of i is size here.
Code Attached for insertion function
void insertion(int *arr, int size){
if(size <= 1)return;
int i, maxIndex = 0;
for(i = 0; i < size; i++){
if(arr[i] > arr[maxIndex]) maxIndex = i;
}
swap(&arr[maxIndex], &arr[size-1]);
insertion(arr, size - 1);
}
The way to debug are many, you can learn to use the gnu debugger which is gdb or use print statements to find out where your code is going wrong.

Generating an NxN magic square using a dynamically allocated 2D array in C++ with user-input dimension

I'm trying to generate and solve an NxN odd-numbered magic square through dynamic memory allocation but whenever I run the code, it displays nothing on the terminal and the programme ends. I reckon it has something to do with the dynamic allocation of the 2D array, as when I make a normal NxN array with a constant size, the programme runs fine. I'd appreciate any help regarding this!
#include<bits/stdc++.h>
#include<cmath>
using namespace std;
void calcuateMagicSquare(int N)
{
int **Array;
Array=new int*[N];
for(int i=0; i<N; i++)
{
Array[i]=new int[N];
}
memset(Array, 0, sizeof(Array));
int nSquare=N*N;
int i=N/2;
int j=N-1;
for(int k=1; k<=nSquare;)
{
if(i==-1 && j==N)
{
j=N-2;
i=0;
}
else
{
if(j==N)
{
j=0;
}
if(i<0)
{
i=N-1;
}
}
if(Array[i][j])
{
j=j-2;
i++;
continue;
}
else
{
Array[i][j]=k++;
}
j++;
i--;
}
int SolutionMagicSquare=N*(N*N+1)/2;
cout << "Solution of the magic Square: " << SolutionMagicSquare << endl;
cout << "MAGIC SQUARE: \n" << endl;
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
cout << setw(4) << Array[i][j] << " ";
cout << endl;
}
}
}
int main()
{
int N;
cout << "Please enter the dimension of the magic square:" << endl;
cin >> N;
calcuateMagicSquare(N);
}
This isn't too bad.
int ** Array=new int*[N];
for(int i=0; i<N; i++)
{
Array[i]=new int[N];
}
memset(Array, 0, sizeof(Array));
The memset is causing your trouble, and it's wrong for two reasons. First, let's say you really wanted to do that. You don't, but let's say you did. How big is sizeof(Array). Array is an int **. On a 64-bit machine, that's 8 bytes. So conveniently, you only destroyed the first pointer.
What you really need to do is this:
int ** Array=new int*[N];
// Don't do this memset, but showing you what it should look like)
memset(Array, 0, sizeof(int *) * N);
for(int i=0; i<N; i++)
{
Array[i]=new int[N];
// But this one is safe
memset(Array[i], 0, sizeof(int) * N);
}
Your version was erasing the first pointer -- Array[0]. I put that first memset in there so you could see what it would look like if you needed it. It's the second one you need. You're clearing out the size of an int times the number of ints that you have.

Please explain the code in this count sort

I was learning count sort from tutorial and my C++ source code is given below:
#include <iostream>
#include <string.h>
using namespace std;
void countSort(int arr[], int size)
{
//declare output array
int output[size];
//declare count array
int count[size];
//initialize count[] with zero
//memset ( void * ptr, int value, size_t num )
memset(count, 0, sizeof(count));
//input array element is the index of count array
//storing the repetition/frequency
for(int i=0; i<size; i++){
count[arr[i]]++;
}
/*
Modify the count array such that each element at
each index stores the sum of previous counts.
*/
// i=1 because, previous is 0 due to avoid -1
for(int i=1; i<size; i++){
count[i] += count[i-1];
}
//Build ouput array
//count array element is the index of output array
for(int i=0; i<size; i++){
//***********THIS LINE***********
output[count[arr[i]]-1] = arr[i];
count[arr[i]]--;
}
//copy ouput array into input array arr[]
for(int i=0; i<size; i++){
arr[i] = output[i];
}
}
void printArray(int arr[], int size){
// Ascending order
for(int i=0; i<size; i++){
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main() {
// your code goes here
int arr[] = {1,4,1,2,7,5,2,6,6,9};
int size= sizeof(arr)/sizeof(arr[0]);
countSort(arr, size);
printArray(arr, size);
return 0;
}
I understand about taking sorted array in output array.However why we need to decrements the output index by -1:
output[count[arr[i]]-1] = arr[i];
I didn't understand this part. I try with only output[count[arr[i]]] but it doesn't gave me the correct sorted array.
The array of counts was converted in to an array of ending indices, point one past the end of each logical bucket, so 1 is subtracted from each index. This could be combined to use pre-decrement, and the array scanned backwards:
for(i=size; i; ){
i--;
output[--count[arr[i]]] = arr[i];
}
Getting back to the counts after they are summed up, note that count[0] contains a count of all the elements equal to zero, and count[1] contains a count of all elements == zero and all elements == 1, and so on, so count[0] is the logical size of the bucket that will contain the zeroes, and the size is 1 greater than the index to the last element. The same logic applies to count[1] and so on.
Example code where the counts are converted into starting indices. output[] converted to use new (to avoid stack overflow and some compilers don't support variable length arrays). count[10] assumes the range of numbers is limited to 0 through 9.
#include <iostream>
#include <stdlib.h>
using namespace std;
void countSort(int arr[], int size)
{
//declare output array
int * output = new int[size];
//declare count array
// assumes range of values is 0 to 9
int count[10];
//initialize count[] with zero
for(int i=0; i<size; i++)
count[i] = 0;
//input array element is the index of count array
//storing the repetition/frequency
for(int i=0; i<size; i++){
count[arr[i]]++;
}
// convert counts into starting indices (this is the main change)
int sum = 0, tmp;
for(int i=0; i<size; i++){
tmp = count[i];
count[i] = sum;
sum += tmp;
}
//Build ouput array
//count array element is the index of output array
for(int i=0; i<size; i++){
output[count[arr[i]]++] = arr[i];
}
//copy ouput array into input array arr[]
for(int i=0; i<size; i++){
arr[i] = output[i];
}
delete[] output;
}
void printArray(int arr[], int size){
// Ascending order
for(int i=0; i<size; i++){
cout<<arr[i]<<" ";
}
cout<<endl;
}
int main() {
int arr[] = {1,4,1,2,7,5,2,6,6,9};
int size= sizeof(arr)/sizeof(arr[0]);
countSort(arr, size);
printArray(arr, size);
return 0;
}

3D Variable length arrays (error-Segmentation fault core dumped) C++

I'm trying to create a variable size 3D VLA, I've seen the algorithm for writing a variable 2D arrays and tried to do it for 3D and facing the error segmentation fault and core dumped here is the code I wrote:
#include <iostream>
using namespace std;
int main (){
double ***array;
int columns,rows,d3;
cin>>columns>>rows>>d3;
array = new double **[d3];
for (int i=0;i<d3;i++){
array[i] = new double *[rows];
}
for (int i=0;i<d3;i++){
for (int j=0;j<rows;j++){
array[i][j] = new double [columns];
}
}
for (int i=0;i<d3;i++){
for (int j=0;j<rows;j++){
delete [] array[i][j];
}
}
for (int i=0;i<d3;i++){
delete [] array[i];
}
delete[]array;
int p=0;
for (int k=0;k<d3;k++){
for (int i=0; i<rows;i++){
for (int j=0; j<columns; j++){
array [k][i][j] = 0;
p =p+1;
}
}
}
cout<<p;
}

assigning values for two dynamic arrays

hope you doing well.
so i have just started to do an assignment and the first thing i wanted to do was to create the two dynamic array. however, there is something wrong with the array i can't assign values to it. Here is the code:
void Room::memory(int **array){
int x,x2;
int count=0;
cout << "Array size? rows: columns: \n";
cin >> x >> x2;
array = new int*[x];
for(int i=0; i<x;i++){
array[i]= new int[x2];
}
for(int i=0; i<x; i++){
for(int j=0; j<x2; j++){
array[i][j]=count;
count++;
}
}
for(int i=0; i<x;i++){
array[i]= new int[x2];
}
for(int i=0; i<x; i++){
for(int j=0; j<x2; j++){
cout<< array[i][j]<< " | ";
}
cout << endl;
}
}
i always get the value 0 for my array. whether i use this line or not:
array[i][j]=count;
i tied to compare my code with someone else and it is the same steps but it doesn't work for me.
class Room{
private:
int **array;
public:
void memory(int **array);
};
Why do you do
for(int i=0; i<x;i++){
array[i]= new int[x2];
} twice?
at the same time, please change void memory(int **array); to void memory();
while you crested the 2nd 2D dynamic array,you did not initialize it...And just printed it... In the 2nd 2D array you also need to initialize before printing the all index values....
for(int i=0; i<x;i++){
array[i]= new int[x2];
}
//here should be the initialization
for(int i=0; i<x; i++){
for(int j=0; j<x2; j++){
cout<< array[i][j]<< " | ";
}
cout << endl;
}