i'm an trying to write a program that will call a function win if there is n number of X's or O's in a row. I am have difficulty with the diagonal win that slopes upwards. can any offer any advice on what I should change? Thanks in advance. It calls an infinite loop instead of returning true.
bool left_diag_win(char **board, int num_rows, int num_cols) {
int i;
if (board[0][0] == '*') {
return false;
}
for (i = 1; i < num_rows; ++i) {
if (board[i][i] != board[0][0]) {
return false;
}
}
return true;
}
bool right_diag_win(char **board, int num_rows, int num_cols) {
int i;
if (board[0][num_cols - 1] == '*') {
return false;
}
for (i = 1; i < num_rows; ++i) {
if (board[i][num_cols - i - 1] != board[0][num_cols - 1]) {
return false;
}
}
return true;
}
You code seems correct, but you probably have a problem elsewhere. Here is an example where it behaves as expected:
#include <stdbool.h>
#include <stdio.h>
bool left_diag_win(char **board, int num_rows, int num_cols) {
if (board[0][0] == '*') {
return false;
}
for (int i = 1; i < num_rows; ++i) {
if (board[i][i] != board[0][0]) {
return false;
}
}
return true;
}
bool right_diag_win(char **board, int num_rows, int num_cols) {
if (board[0][num_cols - 1] == '*') {
return false;
}
for (int i = 1; i < num_rows; ++i) {
if (board[i][num_cols - i - 1] != board[0][num_cols - 1]) {
return false;
}
}
return true;
}
int main(void) {
char *matrix1[] = { "X****", "*X***", "**X**", "***X*", "****X" };
char *matrix2[] = { "****X", "***X*", "**X**", "*X***", "X****" };
printf("matrix:\n");
for (int i = 0; i < 5; i++) {
printf("%s\n", matrix1[i]);
}
printf("left-diagonal: %d\n", left_diag_win(matrix1, 5, 5));
printf("right-diagonal: %d\n\n", right_diag_win(matrix1, 5, 5));
printf("matrix:\n");
for (int i = 0; i < 5; i++) {
printf("%s\n", matrix2[i]);
}
printf("left-diagonal: %d\n", left_diag_win(matrix2, 5, 5));
printf("right-diagonal: %d\n\n", right_diag_win(matrix2, 5, 5));
return 0;
}
Output:
matrix:
X****
*X***
**X**
***X*
****X
left-diagonal: 1
right-diagonal: 0
matrix:
****X
***X*
**X**
*X***
X****
left-diagonal: 0
right-diagonal: 1
Related
I´m facing really weird issue with my headtail application. When I try to read from file data.txt using Powershell (command: Get-Content data.txt | .\Headtail.exe head 10) I always get proper and expected output. However if I change input from data.txt to fail.txt I won´t get any output from output function (called vypis()).
Does anyone have an idead what is going on here?
GOOD CASE: Output from command (this output is suppose to be same using fail.txt as an input (meaning that content of the given input should be printed)) Get-Content data.txt | .\Headtail.exe head 10 in PowerShell:
aaaaaaaaaaaaaaaaaaaaaaaaaaaa.
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.
ccccccccccccccccccccc.
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
WRONG CASE: Output from command Get-Content fail.txt | .\Headtail.exe head 10 in PowerShell:
/*NOTHING */
Code for my headtail function is following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int const size = 15;
int last_changed = 0;
typedef struct {
char **field;
int *columns;
int rows;
} TMatrix;
void set_size(TMatrix* matrix) {
for (int i = 0; i < matrix->rows; i++) matrix->columns[i] = size;
}
TMatrix* allocate() {
TMatrix* matrix = malloc(sizeof(TMatrix));
if (!matrix) return NULL;
matrix->field = malloc(size * sizeof(char*));
if (!matrix->field) return NULL;
matrix->rows = size;
matrix->columns = malloc(size * sizeof(int));
if (!matrix->field) return NULL;
set_size(matrix);
for (int i = 0; i < matrix->rows; i++) {
matrix->field[i] = malloc(size * sizeof(char));
if (!matrix->field[i]) return NULL;
}
return matrix;
}
void release(TMatrix* matrix) {
for(int i = 0; i < matrix->rows; i++) free(matrix->field[i]);
free(matrix->field);
free(matrix->columns);
free(matrix);
}
bool add_rows(TMatrix* matrix) {
matrix->rows += 10;
char** rebuf = realloc(matrix->field, matrix->rows * sizeof(char*));
if (!rebuf) {
free(rebuf);
return false;
}
matrix->field = rebuf;
int* rebufl = realloc(matrix->columns, matrix->rows * sizeof(int));
if (!rebufl) {
free(rebufl);
return false;
}
matrix->columns = rebufl;
for (int i = 1; i <= 10; i++) {
char* rebuh = realloc(matrix->field[matrix->rows - i], size * sizeof(char));
if (!rebuh) {
free(rebuh);
return false;
}
matrix->field[matrix->rows - i] = rebuh;
matrix->columns[matrix->rows - i] = size;
}
return true;
}
bool add_column(TMatrix* matrix, int row) {
matrix->columns[row] += 15;
char* rebuf = realloc(matrix->field[row], matrix->columns[row] * sizeof(char));
if (!rebuf) {
free(rebuf);
return false;
}
matrix->field[row] = rebuf;
return true;
}
TMatrix* load(FILE* in) {
char c;
int actual_row = 0, actual_column = 0;
TMatrix* matrix;
if (!(matrix = allocate())) return NULL;
while ((fscanf(in, "%c", &c)) != EOF) {
matrix->field[actual_row][actual_column] = c;
if (c != '\n') {
actual_column += 1;
if (((matrix->columns[actual_row]) - 1) == actual_column) {
if (!add_column(matrix, actual_row)) return NULL;
}
}
else if (c == '\n') {
actual_column +=1;
if (((matrix->columns[actual_row]) - 1) == actual_column) {
if (!add_column(matrix, actual_row)) return NULL;
}
matrix->field[actual_row][actual_column] = '\0';
actual_column = 0;
actual_row += 1;
last_changed += 1;
if (((matrix->rows) - 1) == actual_row) {
if (!add_rows(matrix)) return NULL;
}
}
}
return matrix;
}
bool output(FILE* out, TMatrix *matrix, double num_of_output_lines, char method[]) {
if (!matrix) return false;
if (num_of_output_lines <= 0) return false;
if (matrix->rows <= 0) return false;
if (num_of_output_lines > last_changed) return false;
if (strcmp("head", method) == 0) {
for (int i = 0; i < num_of_output_lines; i++) {
for (int j = 0; j < matrix->columns[i]; j++) {
if (matrix->field[i][j] != '\0') fprintf(out, "%c", matrix->field[i][j]);
else break;
}
}
}
else if (strcmp("tail", method) == 0) {
for (int a = (last_changed-1); a >= (last_changed - num_of_output_lines); a--) {
for (int b = 0; b < matrix->columns[a]; b++) {
if (matrix->field[a][b] != '\0') fprintf(out, "%c", matrix->field[a][b]);
else break;
}
}
}
else return false;
return true;
}
void Help() {
fprintf(stdout, "-------------------------------------------------------------------------------------\n");
fprintf(stdout, "* Help function - nothing important *\n");
fprintf(stdout, "-------------------------------------------------------------------------------------\n");
}
int main(int argc, char *argv[])
{
if (argc < 3 || argc > 4) {
printf("!Valid count of arguments entered! \n");
return -1;
}
if (strcmp("-h", argv[1]) == 0) Help();
double num_of_output_lines = atoi(argv[argc - 1]);
TMatrix* matrix = load(stdin);
if (!matrix) {
printf("!Error while loading! \n");
return -1;
}
if (!output(stdout, matrix, num_of_output_lines, argv[argc - 2])) {
printf("!Error while printing! \n");
return -1;
}
release(matrix);
return 0;
}
And content of data.txt (works fine, just an example input):
aaaaaaaaaaaaaaaaaaaaaaaaaaaa.
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.
ccccccccccccccccccccc.
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.
nnnnnnnnnnnnnnnnnnnnnnnnn.
ooooooooooo.
ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp.
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss.
ttttttttttttttttttttt.
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.
vvvvvvvvvvvvvvvvvvvvvvvvvvv.
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.
zzzzzzzzzzzzzzzzzzzzzz.
And finally content of fail.txt (didn´t get any output, the difference is just in length of some rows):
aaaaa.
bbbbbbb.
cccc.
ddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.
nnnnnnnnnnnnnnnnnnnnnnnnn.
ooooooooooo.
ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp.
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss.
ttttttttttttttttttttt.
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.
vvvvvvvvvvvvvvvvvvvvvvvvvvv.
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.
zzzzzzzzzzzzzzzzzzzzzz.
I am writing a program to solve Sudoku puzzles in C I declared the array in main() when I try and access it in a different function the compiler gives the error I've tried using pointers to the array but nothing seems to allow me to access it
error: ‘grid’ undeclared (first use in this function) 121 |
printf("%d ", &grid[i][i]);
How can I access this array from a different function?
Here is the code
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
int grid[9][9] =
{
{8,0,0,0,0,0,0,0,0},
{0,0,3,6,0,0,0,0,0},
{0,7,0,0,9,0,2,0,0},
{0,5,0,0,0,7,0,0,0},
{0,0,0,0,4,5,7,0,0},
{0,0,0,1,0,0,0,3,0},
{0,0,1,0,0,0,0,6,8},
{0,0,8,5,0,0,0,1,0},
{0,9,0,0,0,0,4,0,0}
};
int LineNum = 9;
int RowAmount = 9;
for (int i = 0; i < LineNum; ++i)
{
for (int i = 0; i < RowAmount; ++i)
{
printf("%d ", &grid[i][i]);
}
printf("\n");
}
}
int find_empty_box(int sudoku)
{
for (int x = 0; x <= 9; ++x)
{
for (int y = 0; y < 9; ++y)
{
if (sudoku[&x][&y] == 0)
{
return x, y;
}
}
return NULL, NULL;
}
}
int Answer_Valid(int sudoku, int guess, int row, int col)
{
int row_values = &sudoku[&row];
for (int i = 0; i < sudoku[&row]; ++i)
{
if (guess == sudoku[&row[&i]])
{
return false;
}
}
int column_values = &sudoku[&col];
for (int t = 0; t <= 9; ++t)
{
for (int n = 0; n < &sudoku[&col]; ++n)
{
if (&guess == &sudoku[&col[&n]])
{
return false;
}
}
}
int row_start = (row / 3) * 3;
int col_start = (col / 3) * 3;
for (int x = 0; x <= row_start && row_start + 3; ++x)
{
for (int y = 0; y < col_start && col_start + 3; ++y)
{
if (sudoku[&x][&y] == guess)
{
return false;
}
return true;
}
}
}
int Solver(sudoku, guess)
{
int row, col = find_empty_box(sudoku);
if (row == NULL)
{
return true;
}
for (int i = 0; i < 1||2||3||4||5||6||7||8||9; ++i)
{
if(Answer_Valid(sudoku, guess, row, col))
{
sudoku[&row][&col] = guess;
if(Solver(sudoku))
{
return true;
}
return false;
}
}
int LineNum = 9;
int RowAmount = 9;
for (int i = 0; i < LineNum; ++i)
{
for (int i = 0; i < RowAmount; ++i)
{
printf("%d ", &grid[i][i]);
}
printf("\n");
}
}
I've written this code for BFS, but after showing the result it crashes. I don't find anything wrong with my code. Here's the code
I think this is pointer related problem, because I got the same problem because I did not allocate memeory. Visual studio debugger shows there's a problem in this function.
int getAdjUnvisitedVertex(int vertexIndex) {
for (int j = 0; j < vertexCount; ++j) {
if (adjMatrix[vertexIndex][j] == 1 && vertices[j]->visited == false) { //Is there anything wrong in this logic?
return j;
}
}
return 0;
}
Any help will be much appreciated. This is my full code. DFS is working, its BFS that causing problems.
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<malloc.h>
#include<stdbool.h>
#define SIZE 50
int vertexCount;
struct vertex {
char label;
bool visited;
};
struct vertex *vertices[SIZE];
int adjMatrix[SIZE][SIZE];
int stack[SIZE];
int queue[SIZE];
int top = -1;
int front = -1;
int rear = -1;
void menu();
void addVertex();
void addEdges();
void push(char);
void pop();
void enQueue(char);
int deQueue();
void displayAdjMatrix();
void displayVertex(int);
int getAdjUnvisitedVertex(int);
void DFS();
void BFS();
bool isStackEmpty();
bool isQueueEmpty();
int main() {
menu();
addVertex();
addEdges();
puts("\nDepth first search:");
DFS();
puts("\nBreadth first search:");
BFS();
}
void menu() {
puts("How many vertices?");
scanf("%d", &vertexCount);
}
void addVertex() {
int ascii = (int)'A';
puts("Vertices are:");
for (int i = 0; i < vertexCount; ++i, ++ascii) {
vertices[i] = (struct vertex*)calloc(vertexCount, sizeof(struct vertex));
vertices[i]->label = (char)ascii;
vertices[i]->visited = false;
printf("%c ", vertices[i]->label);
}
}
void addEdges() {
puts("\nEnter edges:");
for (int i = 0; i < vertexCount; ++i) {
for (int j = i + 1; j < vertexCount; ++j) {
printf("%c->%c: ", vertices[i]->label, vertices[j]->label);
scanf("%d", &adjMatrix[i][j]);
if (adjMatrix[i][j] == 1) {
adjMatrix[j][i] = 1;
}
}
}
}
void displayAdjMatrix() {
for (int i = 0; i < vertexCount; ++i) {
for (int j = 0; j < vertexCount; ++j) {
printf("%d\t", adjMatrix[i][j]);
}
puts("");
}
}
void push(char data) {
if (top == SIZE - 1) {
puts("Overflow!");
return;
}
stack[++top] = data;
}
void pop() {
if (top == -1) {
puts("Underflow!");
return;
}
stack[top--];
}
int getAdjUnvisitedVertex(int vertexIndex) {
for (int j = 0; j < vertexCount; ++j) {
if (adjMatrix[vertexIndex][j] == 1 && vertices[j]->visited == false) {
return j;
}
}
return 0;
}
void displayVertex(int vertexIndex) {
printf("%c ", vertices[vertexIndex]->label);
}
void DFS() {
vertices[0]->visited = true;
displayVertex(0);
push(0);
while (!isStackEmpty()) {
int unvisitedVertex = getAdjUnvisitedVertex(stack[top]);
if (!unvisitedVertex) {
pop();
}
else {
vertices[unvisitedVertex]->visited = true;
displayVertex(unvisitedVertex);
push(unvisitedVertex);
}
}
for (int i = 0; i < vertexCount; ++i) {
vertices[i]->visited = false;
}
}
bool isStackEmpty() {
if (top == -1) {
return true;
}
return false;
}
bool isQueueEmpty() {
if (front == -1) {
return true;
}
return false;
}
void enQueue(char data) {
if (rear == SIZE - 1) {
puts("Queue is full!");
return;
}
if (front == -1) {
++front;
}
queue[++rear] = data;
}
int deQueue() {
if (front == - 1) {
puts("Queue is empty!");
return 0;
}
int deleted;
deleted = queue[front];
queue[front++] = 0;
return deleted;
}
void BFS() {
vertices[0]->visited = true;
displayVertex(0);
enQueue(0);
while (!isQueueEmpty()) {
int temp = deQueue();
int unvisitedVertex;
while(unvisitedVertex = getAdjUnvisitedVertex(temp)) {
vertices[unvisitedVertex]->visited = true;
displayVertex(unvisitedVertex);
enQueue(unvisitedVertex);
}
}
for (int i = 0; i < vertexCount; ++i) {
vertices[i]->visited = false;
}
}
This is my first post on StackOverflow, so I apologize if I'm doing something wrong. I'm relatively new to C, so I'm sure my code is fairly ugly and hacky in places, however the majority of the code does what I expect it to. I'm having trouble with a precheck method that I'm using to check a sudoku board before I begin feeding it through my solver-logic. I'm redirecting input from a text file with strings that look like
4.....8.5.34.........7......2.....6.....8.4......1.......6.3.7.5..2.....1.4......
4.....8.5.3..........7......2.....6.....8.4......1.......6.3.7.5..2.....1.5......
4.....8.5.3..........7......2.....6.....8.4......1...x...6.3.7.5..2.....1.4......
417369825632158947958724316825437169791586432346912758289643571573291684164875293
417369825632158947958724316825437169791586432346912758289643.71573291684164875293
Each string is (ideally) 81 characters with just digits 1-9 and '.'s. I parse a string into a temp char array, and then use the method fillBoard to transfer the chars in the temp array into a 2d int array. Once this is complete, I call my precheck method. If the filled board doesn't pass the row, column, and box checks, the precheck method returns a one, indicating that the puzzle is not solvable (meaning an error message should be printed and that the program should move on to the next string). For some reason, my precheck method is returning one even for strings that should be solvable. I'm not sure why this is. Any help would be appreciated. Thanks.
#include <stdio.h>
#include <string.h>
int alphaError = 0;
struct Point findEmpty(int board[9][9]);
int usedInBox(int board[9][9], int boxStartRow, int boxStartCol, int num);
int positionSafe(int board[9][9], int row, int col, int num);
int usedInCol(int board[9][9], int col, int num);
int usedInRow(int board[9][9], int row, int num);
int solvePuzzle(int board[9][9]);
int precheck(int board[9][9]);
int main()
{
char c;
int charCount = 0;
int i = 0;
char tempStr[100000];
int board[9][9];
while((fscanf(stdin, "%c", &c)) != EOF)
{
printf("%c", c);
if(c != '\n')
{
if(isalpha(c))
{
alphaError = 1;
}
tempStr[i] = c;
i++;
charCount++;
}
else
{
if(charCount != 81 || alphaError == 1)
{
printf("Error\n\n");
i = 0;
charCount = 0;
alphaError = 0;
}
else
{
fillBoard(board, tempStr);
printBoard(board);
if(precheck(board) == 1)
{
printf("Error\n\n");
}
else
{
if(solvePuzzle(board) == 1)
{
printBoard(board);
}
else
{
printf("No solution\n\n");
}
}
i = 0;
charCount = 0;
}
}
}
return 0;
}
struct Point
{
int x;
int y;
} point;
struct Point findEmpty(int board[9][9])
{
struct Point point1;
point1.x = -1;
point1.y = -1;
int row, col;
for(row = 0; row < 9; row++)
{
for(col = 0; col < 9; col++)
{
if(board[row][col] == 0)
{
point1.x = col;
point1.y = row;
}
}
}
return point1;
}
int usedInBox(int board[9][9], int boxStartRow, int boxStartCol, int num)
{
int row, col;
for(row = 0; row < 3; row++)
{
for(col = 0; col < 3; col++)
{
if(board[row + boxStartRow][col + boxStartCol] == num)
{
return 1;
}
}
}
return 0;
}
int positionSafe(int board[9][9], int row, int col, int num)
{
if((usedInRow(board, row, num)) == 0 && (usedInCol(board, col, num)) == 0 && (usedInBox(board, (row-row%3), (col-col%3), num)) == 0)
{
return 1;
}
else
{
return 0;
}
}
int usedInCol(int board[9][9], int col, int num)
{
int row;
for(row = 0; row < 9; row++)
{
if(board[row][col] == num)
{
return 1;
}
}
return 0;
}
int usedInRow(int board[9][9], int row, int num)
{
int col;
for(col = 0; col < 9; col++)
{
if(board[row][col] == num)
{
return 1;
}
}
return 0;
}
int solvePuzzle(int board[9][9])
{
int num;
struct Point point2;
point2 = findEmpty(board);
if(point2.x == -1)
{
return 1;
}
for(num = 1; num <= 9; num++)
{
if(positionSafe(board, point2.y, point2.x, num) == 1)
{
board[point2.y][point2.x] = num;
if(solvePuzzle(board) == 1)
{
return 1;
}
board[point2.y][point2.x] = 0;
}
}
return 0;
}
void printBoard(int board[9][9])
{
int i, j;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
printf("%d", board[i][j]);
}
}
printf("\n\n");
}
void fillBoard(int board[9][9], char tempStr[100000])
{
int i, j;
int k = 0;
for(i = 0; i < 9; i++)
{
for(j = 0; j < 9; j++)
{
if(tempStr[k] == '.')
{
board[i][j] = 0;
}
else
{
board[i][j] = (tempStr[k] - '0');
}
k++;
}
}
}
int precheck(int board[9][9])
{
int i, j, num;
for(i = 0; i < 9; i++)
{
for(j = 0; j < 9; j++)
{
if(board[i][j] != 0)
{
num = board[i][j];
if(positionSafe(board, i, j, num) == 0)
{
return 1;
}
}
}
}
return 0;
}
So you are using precheck on an already filled board? That might be the problem because usedInCol, usedInRow and usedInBlock will return 1 if the value is already present. So precheck should be used only while filling the board, not after. It will always return 1 if you check values you take from the already filled board.
I have a function that returns a pointer to an array. I'm running it in a loop and free() seems to be giving me problems. I'm not sure where, but it appears that somewhere in the main loop the memory that I'm trying to free is being used. I'm using Xcode 3.2.1 in 10.6 | Debug | x86_64 build.
The program will run through the main loop one time; the second time it encounters the free() it gives me the following error:
malloc: *** error for object 0x100100180: incorrect checksum for freed object -
object was probably modified after being freed.
Can someone point out (no pun intended) what I'm doing wrong with pointers here?
Here is the program:
int main(int argc, char **argv) {
int *partition;
int lowerLimit;
int upperLimit;
// snip ... got lowerLimit and upperLimit from console arguments
// this is the 'main loop':
for (int i = lowerLimit; i <= upperLimit; i += 2) {
partition = goldbachPartition(i);
printOutput(partition[0], partition[1], i);
free(partition); // I get problems on the second iteration here
}
return 0;
}
int *goldbachPartition(int x) {
int solved = 0;
int y, z;
int *primes;
int *result;
result = intAlloc(2);
primes = atkinsPrimes(x);
for (int i = intCount(primes)-1; i >= 0; i--) {
y = primes[i];
for (int j = 0; j < y; j++) {
z = primes[j];
if (z + y >= x) {
break;
}
}
if (z + y == x) {
solved = 1;
result[0] = y;
result[1] = z;
break;
} else if (y == z) {
result[0] = 0;
result[1] = 0;
break;
}
}
free(primes);
return result;
}
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int counter = 0;
int sqrtLimit;
int xLimit;
int resultsSize;
primes = intAlloc(limit+1);
intFillArray(primes, limit+1, 0);
sqrtLimit = floor(sqrt(limit));
xLimit = floor(sqrt((limit+1) / 2));
// these loops are part of the Atkins Sieve implementation
for (int x = 1; x < xLimit; x++) {
int xx = x*x;
for (int y = 1; y < sqrtLimit; y++) {
int yy = y*y;
int n = 3*xx + yy;
if (n <= limit && n % 12 == 7) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
n += xx;
if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
if (x > y) {
n -= xx + 2*yy;
if (n <= limit && n % 12 == 11) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
}
}
}
for (int n = 5; n < limit; n++) {
if (primes[n] == 1) {
for (int k = n*n; k < limit; k += n*n) {
primes[k] = 0;
}
}
}
initialPrimes = intAlloc(2);
if (limit >= 2) {
initialPrimes[counter++] = 2;
}
if (limit >= 3) {
initialPrimes[counter++] = 3;
}
filtered = intFilterArrayKeys(primes, limit+1);
results = intMergeArrays(initialPrimes, filtered, counter, trueCount(primes, limit+1));
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered);
results[resultsSize] = 0;
return results;
}
int trueCount(int *subject, int arraySize) {
int count = 0;
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
count++;
}
}
return count;
}
int intCount(int *subject) {
// warning: expects 0 terminated array.
int count = 0;
while (*subject++ != 0) {
count++;
}
return count;
}
void intFillArray(int *subject, int arraySize, int value) {
for (int i = 0; i < arraySize; i++) {
subject[i] = value;
}
}
int *intFilterArrayKeys(int *subject, int arraySize) {
int *filtered;
int count = 0;
filtered = intAlloc(trueCount(subject, arraySize));
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
filtered[count++] = i;
}
}
return filtered;
}
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2) {
int *merge;
int count = 0;
merge = intAlloc(arraySize1 + arraySize2);
for (int i = 0; i < arraySize1; i++) {
merge[count++] = subject1[i];
}
for (int i = 0; i < arraySize2; i++) {
merge[count++] = subject2[i];
}
return merge;
}
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if (ptr == NULL) {
printf("Error: NULL pointer\n");
}
return ptr;
}
void printOutput(int num1, int num2, int rep) {
if (num1 == 0) {
printf("%d: No solution\n", rep);
exit(0);
} else {
printf("%d = %d + %d\n", rep, num1, num2);
}
}
Why is intAlloc not returning int* ?
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if(ptr == NULL) {
printf("Error: NULL pointer\n");
exit(1);
}
return ptr; //like this
}
EDIT (after your update):
On atkinsPrimes() where is filtered being intAlloc()ed?
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int resultsSize;
primes = intAlloc(limit+1);
// ...
initialPrimes = intAlloc(2);
// ...
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered); // Where was it intAlloc()ed?
results[resultsSize] = 0; // make the array 0-terminated to make it easier to work with
return results;
}
EDIT (after your N-th update):
This is a compilable version of your code. It ran smooth on my machine, no crashes. Compiled with g++ (due to declarations of variables inside the for statement):
g++ (Debian 4.3.2-1.1) 4.3.2
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int *goldbachPartition(int x);
int *atkinsPrimes(int limit);
int trueCount(int *subject, int arraySize);
int intCount(int *subject) ;
void intFillArray(int *subject, int arraySize, int value);
int *intFilterArrayKeys(int *subject, int arraySize);
int *intAlloc(int amount);
void printOutput(int num1, int num2, int rep) ;
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2);
int main(int argc, char **argv) {
if (argc < 3) {
printf("Usage: ./program <lower> <upper>\n");
return 0;
}
int *partition;
int lowerLimit = atoi(argv[1]);
int upperLimit = atoi(argv[2]);
// snip ... got lowerLimit and upperLimit from console arguments
// this is the 'main loop':
for (int i = lowerLimit; i <= upperLimit; i += 2) {
partition = goldbachPartition(i);
printOutput(partition[0], partition[1], i);
free(partition); // I get problems on the second iteration here
}
return 0;
}
int *goldbachPartition(int x) {
int solved = 0;
int y, z;
int *primes;
int *result;
result = intAlloc(2);
primes = atkinsPrimes(x);
for (int i = intCount(primes)-1; i >= 0; i--) {
y = primes[i];
for (int j = 0; j < y; j++) {
z = primes[j];
if (z + y >= x) {
break;
}
}
if (z + y == x) {
solved = 1;
result[0] = y;
result[1] = z;
break;
} else if (y == z) {
result[0] = 0;
result[1] = 0;
break;
}
}
free(primes);
return result;
}
int *atkinsPrimes(int limit) {
int *primes;
int *initialPrimes;
int *filtered;
int *results;
int counter = 0;
int sqrtLimit;
int xLimit;
int resultsSize;
primes = intAlloc(limit+1);
intFillArray(primes, limit+1, 0);
sqrtLimit = floor(sqrt(limit));
xLimit = floor(sqrt((limit+1) / 2));
for (int x = 1; x < xLimit; x++) {
int xx = x*x;
for (int y = 1; y < sqrtLimit; y++) {
int yy = y*y;
int n = 3*xx + yy;
if (n <= limit && n % 12 == 7) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
n += xx;
if (n <= limit && (n % 12 == 1 || n % 12 == 5)) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
if (x > y) {
n -= xx + 2*yy;
if (n <= limit && n % 12 == 11) {
primes[n] = (primes[n] == 1) ? 0 : 1;
}
}
}
}
for (int n = 5; n < limit; n++) {
if (primes[n] == 1) {
for (int k = n*n; k < limit; k += n*n) {
primes[k] = 0;
}
}
}
initialPrimes = intAlloc(2);
if (limit >= 2) {
initialPrimes[counter++] = 2;
}
if (limit >= 3) {
initialPrimes[counter++] = 3;
}
filtered = intFilterArrayKeys(primes, limit+1);
results = intMergeArrays(initialPrimes, filtered, counter, trueCount(primes, limit+1));
resultsSize = counter + trueCount(primes, limit+1);
free(primes);
free(initialPrimes);
free(filtered);
results[resultsSize] = 0;
return results;
}
int trueCount(int *subject, int arraySize) {
int count = 0;
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
count++;
}
}
return count;
}
int intCount(int *subject) {
// warning: expects 0 terminated array.
int count = 0;
while (*subject++ != 0) {
count++;
}
return count;
}
void intFillArray(int *subject, int arraySize, int value) {
for (int i = 0; i < arraySize; i++) {
subject[i] = value;
}
}
int *intFilterArrayKeys(int *subject, int arraySize) {
int *filtered;
int count = 0;
filtered = intAlloc(trueCount(subject, arraySize));
for (int i = 0; i < arraySize; i++) {
if (subject[i] == 1) {
filtered[count++] = i;
}
}
return filtered;
}
int *intMergeArrays(int *subject1, int *subject2, int arraySize1, int arraySize2) {
int *merge;
int count = 0;
merge = intAlloc(arraySize1 + arraySize2);
for (int i = 0; i < arraySize1; i++) {
merge[count++] = subject1[i];
}
for (int i = 0; i < arraySize2; i++) {
merge[count++] = subject2[i];
}
return merge;
}
int *intAlloc(int amount) {
int *ptr;
ptr = (int *)malloc(amount * sizeof(int));
if (ptr == NULL) {
printf("Error: NULL pointer\n");
}
return ptr;
}
void printOutput(int num1, int num2, int rep) {
if (num1 == 0) {
printf("%d: No solution\n", rep);
exit(0);
} else {
printf("%d = %d + %d\n", rep, num1, num2);
}
}
Since you are still omitting some source, I can only imagine that the problem is hidden there.
EDIT: (my last update)
To assist your debugging, you should replace your main() function by the one below:
int main(int argc, char **argv)
{
int *primes = NULL;
primes = atkinsPrimes(44); // Evil magic number
free(primes);
return 0;
}
Having a minimal example to reproduce the behavior you pointed out is much better then the whole thing. Have fun with atkinsPrimes(44)