Related
I am working on a sudoku exercise using the backtracking algorithm using C. It prints the gameboard with the first solution it finds, however it does not stop there and continues the recursion by removing the fields of the gameboard and creates a new solution. The problem is somewhere in the solve function. Here is my approach:
#include "sudoku.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
int field[SIZE][SIZE];
int initial[SIZE][SIZE];
/* Initializes the sudoku array.
* The field initial keeps the original start value for
* figuring out if a value is fixed or can be changed. */
void init(int begin[SIZE][SIZE]) {
memcpy(field, begin, SIZE * SIZE * sizeof(int));
memcpy(initial, begin, SIZE * SIZE * sizeof(int));
}
/* Retrieves the solution. NEEDED FOR AUTO-TESTING PURPOSES. */
void getResult(int result[SIZE][SIZE]){
memcpy(result, field, SIZE * SIZE * sizeof(int));
}
/* pretty prints the sudoku array */
void print() {
int row, col;
// print the first line
printf("||");
for (col = 0; col < SIZE - 1; col++) {
if (col % SQRT_SIZE == SQRT_SIZE - 1)
printf("===++");
else
printf("===+");
}
printf("===||\n");
// loop through all rows of the array
for (row = 0; row < SIZE; row++) {
// print the line with field values
for (col = 0; col < SIZE; col++) {
if (col % SQRT_SIZE == 0)
printf("|| ");
else
printf("| ");
if (field[row][col] == 0)
printf(" ");
else
printf("%d ", field[row][col]);
}
// print the separation line;
// depending on the result of the modulo operation
// print a single or double line
printf("||\n||");
if (row % SQRT_SIZE == SQRT_SIZE - 1) {
for (col = 0; col < SIZE - 1; col++) {
if (col % SQRT_SIZE == SQRT_SIZE - 1)
printf("===++");
else
printf("===+");
}
printf("===||\n");
}
else {
for (col = 0; col < SIZE - 1; col++) {
if (col % SQRT_SIZE == SQRT_SIZE - 1)
printf("---++");
else
printf("---+");
}
printf("---||\n");
}
}
}
/* Checks if the value is valid and can be set into the field.
* The function returns false if the value is already present or
* has been one of the initial values. */
int checkValueInField(int value, int row, int col) {
int i, r, c;
int squareRow;
int squareCol;
// checks for initial values
if (initial[row][col] != 0) {
if (initial[row][col] == value)
return 1;
else
return 0;
}
// check horizontally
for (i = 0; i < SIZE; i++) {
if (field[row][i] == value) return 0;
}
// check vertically
for (i = 0; i < SIZE; i++) {
if (field[i][col] == value) return 0;
}
// check square
squareRow = row / SQRT_SIZE;
squareCol = col / SQRT_SIZE;
for (r = squareRow * SQRT_SIZE; r < squareRow * SQRT_SIZE + SQRT_SIZE; r++) {
for (c = squareCol * SQRT_SIZE; c < squareCol * SQRT_SIZE + SQRT_SIZE; c++) {
if (field[r][c] == value) return 0;
}
}
return 1;
}
/* Set a value in the sudoku field if the field is empty.
* The method returns false if the field contains a fixed number. */
int setValueInField(int value, int row, int col) {
if (initial[row][col] == 0) {
field[row][col] = value;
return 1;
}
else if (initial[row][col] == value)
return 1;
return 0;
}
/* Removes a value in the sudoku field if it doesn't contain an initial value.
* The method returns false if the field contains a fixed number and cannot be
* removed. */
int removeValueFromField(int row, int col) {
if (initial[row][col] == 0) {
field[row][col] = 0;
return 1;
}
return 0;
}
/* Returns the value in the field */
int getValueFromField(int row, int col) {
return field[row][col];
}
/* Return true after a valid solution for the sudoku has been found. */
int solve(int row, int col) {
print();
bool isSet = false;
if (row == 0 && col == 0) {
for (int i = 1; i <= SIZE; i++) {
if (checkValueInField(i, row, col) && getValueFromField(row, col) == 0) {
isSet = setValueInField(i, row, col);
if (isSet) {
solve(row, col);
}
if (row == SIZE - 1 && col == SIZE - 1) {
return 1;
}
else {
removeValueFromField(row, col);
}
}
}
}
if (row == SIZE - 1 && col == SIZE - 1) {
//Here is the solution, but then it continues after returning 1
for (int r = 1; r <= SIZE; r++) {
for (int c = 1; c <= SIZE; c++) {
if (getValueFromField(r, c) != 0) {
return 1;
}
}
}
}
if (row == SIZE - 1) {
row = 0;
col = col++;
}
else {
row = row++;
}
for (int i = 1; i <= SIZE; i++) {
if (checkValueInField(i, row, col) == 1) {
isSet = setValueInField(i, row, col);
solve(row, col);
if (row == SIZE - 1 && col == SIZE == -1) {
return 1;
}
else {
removeValueFromField(row, col);
}
}
}
return 1;
}
This is my header file:
#ifndef _SUDOKU_H_
#define _SUDOKU_H_
#define SIZE 9
#define SQRT_SIZE 3
void init(int begin[SIZE][SIZE]);
void getResult(int result[SIZE][SIZE]);
void print();
int checkValueInField(int value, int row, int col);
int setValueInField(int value, int row, int col);
int removeValueFromField(int row, int col);
int getValueFromField(int row, int col);
int solve(int row, int col);
This is the initial gameboard and its solution:
int initial[SIZE][SIZE] = {
{0, 1, 0, 0, 0, 9, 0, 5, 0},
{0, 9, 0, 0, 0, 0, 4, 8, 0},
{0, 6, 0, 1, 0, 4, 0, 0, 0},
{0, 0, 5, 0, 0, 0, 9, 3, 0},
{0, 0, 0, 7, 0, 2, 0, 0, 0},
{0, 2, 1, 0, 0, 0, 8, 0, 0},
{4, 0, 0, 0, 8, 0, 6, 0, 9},
{0, 0, 0, 0, 6, 0, 5, 0, 3},
{2, 0, 0, 0, 3, 0, 0, 0, 0},
};
int expected[SIZE][SIZE] = {
{3, 1, 4, 8, 7, 9, 2, 5, 6},
{5, 9, 7, 3, 2, 6, 4, 8, 1},
{8, 6, 2, 1, 5, 4, 3, 9, 7},
{7, 4, 5, 6, 1, 8, 9, 3, 2},
{9, 3, 8, 7, 4, 2, 1, 6, 5},
{6, 2, 1, 5, 9, 3, 8, 7, 4},
{4, 7, 3, 2, 8, 5, 6, 1, 9},
{1, 8, 9, 4, 6, 7, 5, 2, 3},
{2, 5, 6, 9, 3, 1, 7, 4, 8},
};
This is my testcase:
TEST_CASE("Test2", "Sudoku")
{
int result = 0;
int actual[SIZE][SIZE];
int initial[SIZE][SIZE] = {
{0, 1, 0, 0, 0, 9, 0, 5, 0},
{0, 9, 0, 0, 0, 0, 4, 8, 0},
{0, 6, 0, 1, 0, 4, 0, 0, 0},
{0, 0, 5, 0, 0, 0, 9, 3, 0},
{0, 0, 0, 7, 0, 2, 0, 0, 0},
{0, 2, 1, 0, 0, 0, 8, 0, 0},
{4, 0, 0, 0, 8, 0, 6, 0, 9},
{0, 0, 0, 0, 6, 0, 5, 0, 3},
{2, 0, 0, 0, 3, 0, 0, 0, 0},
};
int expected[SIZE][SIZE] = {
{3, 1, 4, 8, 7, 9, 2, 5, 6},
{5, 9, 7, 3, 2, 6, 4, 8, 1},
{8, 6, 2, 1, 5, 4, 3, 9, 7},
{7, 4, 5, 6, 1, 8, 9, 3, 2},
{9, 3, 8, 7, 4, 2, 1, 6, 5},
{6, 2, 1, 5, 9, 3, 8, 7, 4},
{4, 7, 3, 2, 8, 5, 6, 1, 9},
{1, 8, 9, 4, 6, 7, 5, 2, 3},
{2, 5, 6, 9, 3, 1, 7, 4, 8},
};
init(initial);
result = solve(0,0);
getResult(actual);
INFO("Test Case: valid Sudoku board failed.");
REQUIRE(memcmp(actual, expected, sizeof(initial)) == 0);
INFO("Test Case: return value not correct.");
REQUIRE(result == 1);
}
I'm trying to replicate a solution from javascript to Ruby where the idea is to build a grid from two arrays and then, running a search on both arrays, change certain elements in the grid.
I think my ruby solution is fairly similar but the grid doesn't look similar.
Any help is much appreciated
Arrays:
nums1 = [1,2,3,2,1]
nums2 = [3,2,1,4,7]
Javascript grid:
``
const dp = new Array(nums1.length + 1).fill(0).map(() => new Array(nums2.length + 1).fill(0));
console.log(dp)
output:
[
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0 ]
]
Ruby grid attempts:
1º attempt
dp = Array.new(nums1.length+1) {Array.new(nums2.length+1, 0)}
p dp
2º attempt:
dp = (0..n).map{|el| el = (0..m).to_a.map{|el| el = 0 }}
p dp
output is the same for both:
[[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]]
Thank you
Given a 2D array where each digit represents a different color, I want to be able to find out if a given node in the array is surrounded completely by one color. For example, in the 2d array below, I want to be able to confirm that the node at [3][3] is completely surrounded by the color represented by "1". Is there an existing common algorithm that accomplishes this?
{{1, 1, 1, 1, 1, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 0, 0},
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 2, 2, 2, 2, 1, 1, 0},
{1, 1, 1, 2, 2, 1, 1, 1},
{1, 1, 1, 2, 2, 2, 2, 1},
{1, 1, 1, 1, 1, 2, 1, 1},
{1, 1, 1, 1, 1, 1, 2, 1}}
EDIT: Sorry I am not asking about whether the target node is immediately surrounded. I am asking about whether if you move out from the target node, you can reach the edge of the array without crossing over the boundary color.
My current code is the following, but it's not quite working
let squaresChecked = []
let squareSurrounded = true
let boardSize = 15
let gameBoard = new Array(boardSize)
for(let i=0; i<gameBoard.length; i++){
gameBoard[i] = Array(boardSize).fill('white')
}
checkSurrounded(x, y, boundaryColor){
if(x >= boardSize || y >= boardSize || x < 0 || y < 0){
squareSurrounded = false
return
}
if(gameBoard[x][y] === boundaryColor){return}
if(squaresChecked.includes(x + ' ' + y)){return}
squaresChecked.push(x + ' ' + y)
checkSurrounded(x+1, y, boundaryColor)
checkSurrounded(x-1, y, boundaryColor)
checkSurrounded(x, y+1, boundaryColor)
checkSurrounded(x, y-1, boundaryColor)
}
This should check for top, left, right, bottom for given cell at row,col in 2D array if surrounded by var surroundedBy (1).
row = 2
col = 2
arr = [[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 2, 2, 2, 2, 1, 1, 0],
[1, 1, 1, 2, 2, 1, 1, 1],
[1, 1, 1, 2, 2, 2, 2, 1],
[1, 1, 1, 1, 1, 2, 1, 1],
[1, 1, 1, 1, 1, 1, 2, 1]]
surroundedBy = 1
if(arr[row-1][col] ===surroundedBy && arr[row+1][col] === surroundedBy && arr[row][col - 1] === surroundedBy && arr[row][col + 1] === surroundedBy) {
console.log('surrounded');
}else{
console.log('not surrounded');
}
I'm tyring to create a frequency counter. Basically, there's an array (testArray) with a bunch of numbers. I need to process those numbers and insert them in another array (probabilityArray). probabilityArray is also 2D array with the 1st row being the unique elements from the test array, the 2nd row being how many times a unique number occurs (Ex. probabilityArray[2][5] represents how often the number at probabilityArray[1][5] occurs). I'm having trouble exiting the rows for loop and I have no idea why.
#include <stdio.h>
#include <stdlib.h>
int histogram() {
}
int entropy() {
}
int main() {
int i, j, k, found = 0, currentPosition = 0, l = 0, x = 0, y = 0;
int testArray[10][10] = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
{11, 12, 13, 14, 15, 16, 17, 18 ,19, 20},
{11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
{11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30}};
int row = sizeof(testArray) / sizeof(testArray[0]);
int col = sizeof(testArray[0]) / sizeof(testArray[0][0]);
int elements = (row * col);
printf("Elements: %d\n", elements);
//printf("Rows: %d\nCols: %d\n", row, col);
int probabilityArray[3][elements];
for(x = 0; x < 3; x++) {
for(y = 0; y < elements; y++) {
//printf("X: %d\tY: %d\t", x, y);
probabilityArray[x][y] = 0;
}
//printf("\n");
}
//printf("Got here\n");
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
printf("%d\n", l);
l++;
int temp = testArray[i][j];
for (k = 0; k < currentPosition; k++) {
if (probabilityArray[1][k] == temp) {
//Element is not unique, increase occurance counter
printf("NOT UNIQUE: %d\n", temp);
probabilityArray[2][k]++;
found = 1;
break;
}
}
if (found == 0) {
//Element is unique, add it to array
printf("FOUND: %d\n", temp);
probabilityArray[1][currentPosition] = temp;
probabilityArray[2][currentPosition]++;
currentPosition++;
printf("Current Position: %d\n", currentPosition);
}
found = 0;
}
printf("I: %d\tC: %d\n", i, j);
}
for (i = 0; i < currentPosition; i++) {
probabilityArray[3][i] = (int)((probabilityArray[2][i] / elements) * 100);
}
for (i = 0; i < currentPosition; i++) {
printf("ELEMENT: %d\t\tFREQUENCY: %d\t\tPROBABILITY:%d\n", probabilityArray[1][i], probabilityArray[2][i], probabilityArray[3][i]);
}
}
Any help is appreciated!
You are using indices 1, 2, and 3, where you probably meant to use 0, 1, and 2.
Here:
if (probabilityArray[1][k] == temp) { // Should it be 0??
//Element is not unique, increase occurance counter
printf("NOT UNIQUE: %d\n", temp);
probabilityArray[2][k]++; // Should it be 1??
and here:
probabilityArray[1][currentPosition] = temp; // Should it be 0??
probabilityArray[2][currentPosition]++; // Should it be 1??
and here:
probabilityArray[3][i] = (int)((probabilityArray[2][i] / elements) * 100);
// Should it be 2 and 1 ??
and here:
printf("ELEMENT: %d\t\tFREQUENCY: %d\t\tPROBABILITY:%d\n",
probabilityArray[1][i], probabilityArray[2][i], probabilityArray[3][i]);
// Should be be 0, 1, and 2
Fixing those might fix your problems.
I've written a small test case program in FORTRAN 90 which initializes a 3d array in slices. Can this same behavior be easily replicated in C?
program fortranEngine
real(4) , dimension(10,10) :: tmp
real(4) , dimension(10,10,3) :: p
tmp = RESHAPE( [ 0.973, 1.053, 0, 0, 0, 0, 0, 0, 0, 0, &
1.053, 1.080, 0, 0, 0, 0, 0, 0, 0, 0, &
1.010, 0.408, 0.442, 0, 0, 0, 0, 0, 0, 0, &
1.119, 0.900, 0.399, 0.762, 0, 0, 0, 0, 0, 0, &
1.211, 0.975, 0.845, 0.952, 1.105, 0, 0, 0, 0, 0, &
1.248, 1.016, 0.485, 0.000, 0.000, 1.110, 0, 0, 0, 0, &
1.225, 1.123, 1.056, 0.000, 0.000, 0.949, 0.832, 0, 0, 0, &
1.138, 1.232, 1.089, 1.050, 0.930, 0.402, 0.789, 0.774, 0, 0, &
1.149, 1.406, 1.201, 1.052, 0.416, 0.878, 0.896, 0.431, 1.144, 0, &
1.351, 1.255, 1.290, 1.358, 1.240, 1.228, 1.257, 1.140, 1.123, 1.228] &
, [10,10] )
p(:,:,1) = tmp
...
end program fortranEngine
You can more or less do it in C99 or C2011, but it isn't as convenient as in Fortran. Beware initialization order; Fortran does it in one order (column-major) and C does it in the other (row-major). Ignoring that, you can do:
float tmp[10][10] =
{
{ 0.973, 1.053, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 1.053, 1.080, 0, 0, 0, 0, 0, 0, 0, 0, },
{ 1.010, 0.408, 0.442, 0, 0, 0, 0, 0, 0, 0, },
{ 1.119, 0.900, 0.399, 0.762, 0, 0, 0, 0, 0, 0, },
{ 1.211, 0.975, 0.845, 0.952, 1.105, 0, 0, 0, 0, 0, },
{ 1.248, 1.016, 0.485, 0.000, 0.000, 1.110, 0, 0, 0, 0, },
{ 1.225, 1.123, 1.056, 0.000, 0.000, 0.949, 0.832, 0, 0, 0, },
{ 1.138, 1.232, 1.089, 1.050, 0.930, 0.402, 0.789, 0.774, 0, 0, },
{ 1.149, 1.406, 1.201, 1.052, 0.416, 0.878, 0.896, 0.431, 1.144, 0, },
{ 1.351, 1.255, 1.290, 1.358, 1.240, 1.228, 1.257, 1.140, 1.123, 1.228 },
};
float p[3][10][10];
for (int i = 0; i < 3; i++)
memmove(p[i], tmp, sizeof(tmp));
Note that I moved the dimension [3] from the end of the declaration to the start of the declaration, though. The other way around would not make much sense in C. So, the notation is more or less available, but details of storage management make it less than obvious how to achieve exactly what you want.
Is this easy enough?
for(int i = 0 ; i < 10 ; ++i)
for(int j = 0 ; j < 10 ; ++j )
p[0][i][j] = tmp[i][j] ;