Skip to content

Commit

Permalink
Merge branch 'master' into tads
Browse files Browse the repository at this point in the history
  • Loading branch information
dcross23 authored Oct 23, 2020
2 parents deb20c5 + d994d64 commit 8973246
Show file tree
Hide file tree
Showing 51 changed files with 4,053 additions and 1 deletion.
1,748 changes: 1,748 additions & 0 deletions Algoritmic Schemes/Backtracking/Eight Queens/allSolutions.txt

Large diffs are not rendered by default.

150 changes: 150 additions & 0 deletions Algoritmic Schemes/Backtracking/Eight Queens/eightQueens.c
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 Algoritmic Schemes/Backtracking/Eight Queens/eightQueens.h
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
70 changes: 70 additions & 0 deletions Algoritmic Schemes/Backtracking/Eight Queens/main.c
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;
}




23 changes: 23 additions & 0 deletions Algoritmic Schemes/Backtracking/Eight Queens/makefile
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 Algoritmic Schemes/Backtracking/Knight Travel/knightTravel.c
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");
}
8 changes: 8 additions & 0 deletions Algoritmic Schemes/Backtracking/Knight Travel/knightTravel.h
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
Loading

0 comments on commit 8973246

Please sign in to comment.