-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
51 changed files
with
4,053 additions
and
1 deletion.
There are no files selected for viewing
1,748 changes: 1,748 additions & 0 deletions
1,748
Algoritmic Schemes/Backtracking/Eight Queens/allSolutions.txt
Large diffs are not rendered by default.
Oops, something went wrong.
150 changes: 150 additions & 0 deletions
150
Algoritmic Schemes/Backtracking/Eight Queens/eightQueens.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
#include <string.h> | ||
#include <stdlib.h> | ||
|
||
#include "eightQueens.h" | ||
|
||
//Counter to store solution number | ||
int solNumber = 1; | ||
|
||
/* Gives 1 solution. | ||
* Backtraking algorithm that solves the N-queens problem. It uses a counter "currentQueen" that marks which queen | ||
* is searching for a box to stay. To know in which boxes a queen can or cannot be it uses 3 arrays that store | ||
* what boxes in each row, diagonal or transversal diagonal are o are not busy. | ||
* | ||
* The algorithm "ignores" colums because boxes are searched according to the next clear column. This is, each column | ||
* can only have 1 queen, so when a queen is stored in a box, the algorithm works recursively with the rest of | ||
* the board ignoring the busy columns used before. | ||
* | ||
* The algorithm finishes when all queens are placed (there is a solution) or when all posible combinations are tried. | ||
* In case there is a solution, it will be returned as and array with the positions in the rows where the queens | ||
* where places: for example, if solution[1] = 4 means that theres a queen in the box [1(row)][4(column)] in the board | ||
*/ | ||
void queensAlg(int currentQueen,int *success,int *solution, int *rows,int *d, int *t, int numQueens){ | ||
int j=-1; | ||
*success = 0; | ||
do{ | ||
j++; | ||
if(rows[j] && d[currentQueen-j+(numQueens-1)] && t[currentQueen+j]){ | ||
//If there is no queen in the box (row/diagonal/transversal diagonal), | ||
// it registers it in that box | ||
solution[currentQueen] = j; | ||
rows[j] = d[currentQueen-j+(numQueens-1)] = t[currentQueen+j] = 0; | ||
|
||
if(currentQueen == (numQueens-1)){ | ||
//If the queen registered was the last queen, it means that all | ||
// queens where correctly placed and it finishes | ||
*success = 1; | ||
|
||
}else{ | ||
//If the queen registered wasnt the last queen, it means that there | ||
// are more queens that remain unplaced, so it continues | ||
queensAlg(currentQueen+1, success, solution, rows, d, t, numQueens); | ||
|
||
//If there is no success placing the queen in that box, it goes back,leaves | ||
// free the box (row/diagonal/transversal diagonal) and continues with the next | ||
// box | ||
if(!(*success)){ | ||
rows[j] = d[currentQueen-j+(numQueens-1)] = t[currentQueen+j] = 1; | ||
} | ||
} | ||
} | ||
|
||
//If there is no success or there are no more boxes remaining (j == (numQueens-1)), it finishes | ||
}while(!(*success) && j!=(numQueens-1)); | ||
} | ||
|
||
|
||
/* Gives all posible solutions | ||
* Backtraking algorithm, same as before, but gives all posible solutions to N-queens problem. | ||
*/ | ||
void queensAlgAllSolutions(int currentQueen,int *solution, int *rows,int *d, int *t, int numQueens, FILE *niceFile){ | ||
int j; | ||
for(j=0; j<numQueens; j++){ | ||
if(rows[j] && d[currentQueen-j+(numQueens-1)] && t[currentQueen+j]){ | ||
solution[currentQueen] = j; | ||
rows[j] = d[currentQueen-j+(numQueens-1)] = t[currentQueen+j] = 0; | ||
|
||
if(currentQueen == (numQueens-1)){ | ||
saveSolution(createBoardSolution(solution,numQueens),niceFile); | ||
solNumber++; | ||
|
||
}else{ | ||
queensAlgAllSolutions(currentQueen+1, solution, rows, d, t, numQueens, niceFile); | ||
} | ||
|
||
rows[j] = d[currentQueen-j+(numQueens-1)] = t[currentQueen+j] = 1; | ||
} | ||
} | ||
} | ||
|
||
|
||
/* Creates a Solution storing the number, the number of queens used and interpreting | ||
* the solution array given by the algorithm transforming it to a bidimensional array | ||
* simultating the chess board. | ||
*/ | ||
Solution* createBoardSolution(int *solution, int numQueens){ | ||
if(solution == NULL || numQueens <=0) return NULL; | ||
|
||
int i,j; | ||
Solution *sol = malloc(sizeof(struct solution)); | ||
sol->num = solNumber; | ||
sol->numQueens = numQueens; | ||
|
||
sol->sol = malloc(numQueens * sizeof(char *)); | ||
if(sol->sol == NULL) | ||
return NULL; | ||
|
||
for(i=0; i<numQueens; i++){ | ||
(sol->sol)[i] = malloc(numQueens * sizeof(char)); | ||
if((sol->sol)[i] == NULL) | ||
return NULL; | ||
} | ||
|
||
for(i=0; i<numQueens; i++){ | ||
for(j=0; j<numQueens; j++){ | ||
sol->sol[i][j]='_'; | ||
} | ||
sol->sol[i][solution[i]]='X'; | ||
} | ||
|
||
return sol; | ||
} | ||
|
||
/* | ||
* Saves a solution in a file. The file can be an external file or the standar output | ||
* file to print via terminal the solution. | ||
*/ | ||
void saveSolution(Solution *solution, FILE *niceFile){ | ||
if(solution == NULL) return; | ||
|
||
if(niceFile != NULL){ | ||
int i,j,k; | ||
|
||
fprintf(niceFile,"SOLUTION %d\n",solution->num); | ||
|
||
for(k=0; k<(solution->numQueens*4+1); k++){ | ||
fprintf(niceFile,"-"); | ||
} | ||
fprintf(niceFile,"\n"); | ||
for(i=0; i<solution->numQueens; i++){ | ||
fprintf(niceFile,"| "); | ||
|
||
for(j=0; j<solution->numQueens; j++){ | ||
fprintf(niceFile,"%c | ",solution->sol[i][j]); | ||
} | ||
|
||
fprintf(niceFile,"\n"); | ||
|
||
for(k=0; k<(solution->numQueens*4+1); k++){ | ||
fprintf(niceFile,"-"); | ||
} | ||
|
||
fprintf(niceFile,"\n"); | ||
} | ||
fprintf(niceFile, "\n"); | ||
|
||
} | ||
} | ||
|
||
|
||
|
25 changes: 25 additions & 0 deletions
25
Algoritmic Schemes/Backtracking/Eight Queens/eightQueens.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#ifndef __EIGHT_QUEENS_H__ | ||
#define __EIGHT_QUEENS_H__ | ||
|
||
#include <stdio.h> | ||
|
||
// Number of queens | ||
#define QUEENS 8 | ||
|
||
//Struct to store solutions | ||
typedef struct solution{ | ||
int num; //To store the solution number | ||
int numQueens; //Number of queens of the solution | ||
char **sol; //Bidimension array to store the board with the solution | ||
}Solution; | ||
|
||
|
||
int solNumber; | ||
|
||
void queensAlg(int currentQueen,int *success,int *x, int *rows,int *d, int *t, int numQueens); | ||
void queensAlgAllSolutions(int currentQueen,int *solution, int *rows,int *d, int *t, int numQueens, FILE *niceFile); | ||
|
||
Solution* createBoardSolution(int *solution, int numQueens); | ||
void saveSolution(Solution *solution, FILE *niceFile); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#include "eightQueens.h" | ||
|
||
int main(int argc, char **argv){ | ||
|
||
int currentQueen=0; //Queen that is searching box to stay | ||
int success; //For 1 solution, indicates if there is a solution or not for the problem | ||
int solution[QUEENS]; //Stores the box where each queen is per row (ej: if solution[0]=4, means | ||
// that the queen is on row 4, column 0 | ||
|
||
int rows[QUEENS]; //Stores the rows that have/not have a queen | ||
int diag[QUEENS*2 -1]; //Stores the diagonals that have/not have a queen | ||
int transDiag[QUEENS*2 -1]; //Stores the transversal diagonals that have/not have a queen | ||
|
||
int i,j,k; | ||
|
||
|
||
// ONE SOLUTION | ||
for(i=0; i<QUEENS; i++){ | ||
solution[i] = 0; | ||
rows[i] = 1; | ||
} | ||
for(i=0; i<(QUEENS*2 -1); i++){ | ||
diag[i] = transDiag[i] = 1; | ||
} | ||
|
||
|
||
queensAlg(currentQueen, &success, solution, rows, diag, transDiag, QUEENS); | ||
|
||
Solution* sol = createBoardSolution(solution, QUEENS); | ||
|
||
if(sol != NULL){ | ||
//Prints the solution via stdout (terminal) | ||
saveSolution(sol, stdout); | ||
|
||
//Stores solution to external file | ||
/* | ||
FILE *f = fopen("solutionQueensAlg.txt","w"); | ||
saveSolution(sol, f); | ||
fclose(f); | ||
*/ | ||
} | ||
|
||
|
||
//ALL SOLUTIONS | ||
for(i=0; i<QUEENS; i++){ | ||
solution[i] = 0; | ||
rows[i] = 1; | ||
} | ||
for(i=0; i<(QUEENS*2 -1); i++){ | ||
diag[i] = transDiag[i] = 1; | ||
} | ||
|
||
|
||
//Prints all solutions via stdout (terminal) | ||
//queensAlgAllSolutions(currentQueen, solution, rows, diag, transDiag, QUEENS, stdout); | ||
|
||
FILE *f2 = fopen("allSolutions.txt","w"); | ||
queensAlgAllSolutions(currentQueen, solution, rows, diag, transDiag, QUEENS, f2); | ||
fclose(f2); | ||
|
||
puts(""); | ||
return 0; | ||
} | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
CC=gcc | ||
#CFLAGS=-c | ||
CFLAGS=-c -g | ||
EXECUTABLE_NAME=eightQueens | ||
|
||
all: $(EXECUTABLE_NAME) | ||
|
||
$(EXECUTABLE_NAME): main.o eightQueens.o | ||
$(CC) $^ -o $@ -lm | ||
|
||
main.o: main.c | ||
$(CC) $(CFLAGS) main.c | ||
|
||
eightQueens.o: eightQueens.c eightQueens.h | ||
$(CC) $(CFLAGS) eightQueens.c | ||
|
||
|
||
clean: | ||
rm *.o | ||
rm $(EXECUTABLE_NAME) | ||
|
||
clean-txt: | ||
rm *.txt |
104 changes: 104 additions & 0 deletions
104
Algoritmic Schemes/Backtracking/Knight Travel/knightTravel.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#include "knightTravel.h" | ||
|
||
/* Backtraking algorithm to solve the knight travel problem. This problem consists on travelling | ||
* all the chess boxes using a knight. | ||
* | ||
* This algorithm uses 2 arrays representing the possible movements for the knight (movX and movY). | ||
* There are 8 possible movements for the knight, ignoring the ones that cause the knight to go out | ||
* of the board. | ||
* The algorithm gets and initial position and calculates the next possible box using this movements, | ||
* checking if the new position is inside the board and the box is free or not. If the box is free, | ||
* it registers the movement in the board and searches recursively using this new position as the | ||
* "initial position" for the next movement. | ||
* | ||
* The algorithm will end when the knight has visited the entire board (there is a solution) or when it | ||
* can no longer move because there are no more possible movements. | ||
*/ | ||
void knightTravel(int num, int *success, int x, int y, int **board, int dim ,int *movX, int *movY){ | ||
*success = 0; | ||
int j = -1; | ||
int xn, yn; | ||
|
||
do{ | ||
j++; | ||
//Moves from x,y calculating the next possible box (xn,yn) | ||
xn = x + movX[j]; | ||
yn = y + movY[j]; | ||
|
||
if((xn<dim && xn>=0) && (yn<dim && yn>=0) && (board[xn][yn]==0)){ | ||
board[xn][yn] = num; | ||
|
||
if(num < dim*dim){ | ||
knightTravel(num+1, success, xn, yn, board, dim, movX, movY); | ||
|
||
if(!(*success)){ | ||
board[xn][yn] = 0; | ||
} | ||
|
||
}else{ | ||
(*success) = 1; | ||
} | ||
} | ||
}while(!(*success) && (j<8)); | ||
} | ||
|
||
|
||
|
||
/* | ||
* Creates a new board and initializes it. | ||
*/ | ||
int **createAndInitBoard(int dim){ | ||
int i,j; | ||
|
||
//Create board | ||
int **board; | ||
board = malloc(dim * sizeof(int *)); | ||
for(i=0; i<dim; i++){ | ||
board[i] = malloc(dim * sizeof(int)); | ||
} | ||
|
||
//Initializes it | ||
for(i=0; i<dim; i++){ | ||
for(j=0; j<dim; j++){ | ||
board[i][j]=0; | ||
} | ||
} | ||
|
||
return board; | ||
} | ||
|
||
|
||
|
||
/* | ||
* Prints the board. | ||
*/ | ||
void printBoard(int **board, int dim){ | ||
int i,j; | ||
|
||
printf("\n"); | ||
for(j=0; j<(dim*5 + 1); j++){ | ||
printf("-"); | ||
} | ||
printf("\n"); | ||
|
||
for(i=0; i<dim; i++){ | ||
printf("| "); | ||
for(j=0; j<dim; j++){ | ||
if(board[i][j] == 1){ | ||
printf("\033[0;31m%2d \033[0m| ",board[i][j]); | ||
}else{ | ||
printf("%2d | ",board[i][j]); | ||
} | ||
} | ||
|
||
printf("\n"); | ||
for(j=0; j<(dim*5 + 1); j++){ | ||
printf("-"); | ||
} | ||
printf("\n"); | ||
} | ||
printf("\n"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef __KNIGHT_TRAVEL_H__ | ||
#define __KNIGHT_TRAVEL_H__ | ||
|
||
void knightTravel(int num, int *success, int x, int y, int **board, int dim ,int *movX, int *movY); | ||
int **createAndInitBoard(int dim); | ||
void printBoard(int **board, int dim); | ||
|
||
#endif |
Oops, something went wrong.