Algunas reinas
Me han retado a hacer un programa que resuelva el problema de las n-reinas. Esta es mi solución en c++ básico: sin class / struct , sin memoria dinámica y sin punteros a función. Solo utilizo assert , printf y system para conseguir la hora de inicio y fin del programa.
El límite práctico parece estar en las 30 reinas, con alrededor de 12 segundos de cálculo.
1. Algunas reinas
#include <stdio.h>
#include <stdlib.h>
#include <cassert>
using namespace std;
const int maxSize = 100;
const int notSeized = maxSize+1;
int seizedAtLevel[maxSize][maxSize];
void initSeized(){
for( int col = 0 ; col < maxSize ; col += 1 ){
for( int row = 0 ; row < maxSize ; row += 1 ){
seizedAtLevel[col][row] = notSeized;
}
}
}
bool seized(const int col, const int row, const int currentLevel ){
return seizedAtLevel[col][row] <= currentLevel;
}
void setSeizedValue(const int col, const int row, const int currentLevel, const int value ){
if( col < 0 || row < 0 || col >= maxSize || row >= maxSize ){
// out of board
return;
}
if( seizedAtLevel[col][row] < currentLevel ){
// already seized by previous queen
return;
}
seizedAtLevel[col][row] = value;
}
void changeSeizedCells(const int row, const int level, const int size, const int value ){
for( int d = 1 ; d < size-level ; d += 1 ){
// same row
setSeizedValue(level+d,row,level,value);
// upwards diagonal
setSeizedValue(level+d,row-d,level,value);
// downwards diagonal
setSeizedValue(level+d,row+d,level,value);
}
}
void dumpSeized(const int size){
for( int row = 0 ; row < size ; row += 1 ){
for( int col = 0 ; col < size ; col += 1 ){
printf( "\t%d", seizedAtLevel[col][row] );
}
printf( "\n");
}
}
bool stillPossible( const int level, const int size ){
for( int col = level+1 ; col < size ; col += 1 ){
int freeCells = 0;
for( int row = 0; row < size ; row += 1 ){
if( !seized(col,row,level) ){
freeCells += 1;
}
}
if( freeCells < col-level-1){
// there are no enough free cells in the column
return false;
}
}
return true;
}
bool placeQueenAtLevel( const int level, const int size, int queensRows[] ){
assert(size < maxSize );
// printf( "\n INTENTANDO NIVEL:%d\n", level);
// dumpSeized(size);
if( level == size ){
return true;
}
for( int row = 0 ; row < size ; row += 1 ){
if( seized(level,row,level) ){
continue;
}
// place queen in col=level, row=row
queensRows[level] = row;
changeSeizedCells(row,level, size,level);
// try next queen
if( stillPossible(level,size) ){
if( placeQueenAtLevel(level+1,size,queensRows) ){
return true;
}
}
// remove queen from col=level, row=row
changeSeizedCells(row,level, size,notSeized);
}
return false;
}
void dumpQueens(int queensRows[], int size){
for( int row = 0 ; row < size ; row += 1 ){
for( int col = 0 ; col < size ; col += 1 ){
const char cell = (col+row)%2==0 ? '.' : ' ';
printf( " %c", queensRows[col]==row ? 'Q' : cell );
}
printf( "\n");
}
}
int main( int argc, char *argv[] ){
system("date");
int currentQueen = 0;
const int size = 31;
int queensRows[size];
initSeized();
bool result = placeQueenAtLevel(0,size,queensRows);
printf( "Conseguido:%s\n", result ? "Si" : "No");
if( result ){
dumpQueens(queensRows, size);
}
system("date");
}
mié 21 oct 2020 10:58:18 CEST mié 21 oct 2020 10:58:34 CEST Conseguido:Si Q . . . . . . . . . . . . . . . . . . . . . . . Q . . . . . . . . Q . . . . . . . . . . . . . . . . . . . . . . . . . . Q . . . . . Q . . . . . . . . . . . . . . . . . . . . . . . Q . . . . . . . . . . . . . . . . . Q . . . . . . . . . . . . . Q . . . . . . . Q . . . . . . . . . . . . . . . . . . . . Q . . . . . . . . . . . Q . . . . . . . . . . . . . . . . Q . . . . . . . . . . . . . . . . . . . . . . . Q . . . . . . . Q . . . . . . . . . . . . . . . . . . . . Q . . . . . . . . . . Q . . . . . . . . . . . . . . . . . . . . . Q . . . . . . . . . . Q . . . . . . . . . . . . . . . . . . . . . . . . Q . . . . . . . . . . . . . Q . . . . . . . . . . . . . . . . . Q . . . . . . . . . . . . . . Q . . . . . . . . . . . . . . . . . Q . . . . . . . . . . . . . Q . . . . . . . . . . . . Q . . . . . . . . . . . . Q . . . . . . . . . . . . . . . . . Q . . . . . . . . . . . . Q . . . . . . . . . . . . . . . . . Q . . . . . . . . . . . . . . Q . . . . . . . . . . . . . Q . . . . . . . . . . .