Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,4 +1,7 @@
|
|||
Solve the [[WP:Eight_queens_puzzle|eight queens puzzle]]. You can extend the problem to solve the puzzle with a board of side NxN. Number of solutions for small values of N is [http://oeis.org/A000170 here].
|
||||
Solve the [[WP:Eight_queens_puzzle|eight queens puzzle]].
|
||||
|
||||
You can extend the problem to solve the puzzle with a board of side NxN.
|
||||
For the number of solutions for small values of N, see [http://oeis.org/A000170 oeis.org].
|
||||
|
||||
;Cf.
|
||||
* [[Knight's tour]]
|
||||
|
|
|
|||
285
Task/N-queens-problem/ABAP/n-queens-problem.abap
Normal file
285
Task/N-queens-problem/ABAP/n-queens-problem.abap
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
TYPES: BEGIN OF gty_matrix,
|
||||
1 TYPE c,
|
||||
2 TYPE c,
|
||||
3 TYPE c,
|
||||
4 TYPE c,
|
||||
5 TYPE c,
|
||||
6 TYPE c,
|
||||
7 TYPE c,
|
||||
8 TYPE c,
|
||||
9 TYPE c,
|
||||
10 TYPE c,
|
||||
END OF gty_matrix,
|
||||
gty_t_matrix TYPE STANDARD TABLE OF gty_matrix INITIAL SIZE 8.
|
||||
|
||||
DATA: gt_matrix TYPE gty_t_matrix,
|
||||
gs_matrix TYPE gty_matrix,
|
||||
gv_count TYPE i VALUE 0,
|
||||
gv_solut TYPE i VALUE 0.
|
||||
|
||||
|
||||
SELECTION-SCREEN BEGIN OF BLOCK b01 WITH FRAME TITLE text-b01.
|
||||
PARAMETERS: p_number TYPE i OBLIGATORY DEFAULT 8.
|
||||
SELECTION-SCREEN END OF BLOCK b01.
|
||||
|
||||
" Filling empty table
|
||||
START-OF-SELECTION.
|
||||
DO p_number TIMES.
|
||||
APPEND gs_matrix TO gt_matrix.
|
||||
ENDDO.
|
||||
|
||||
" Recursive Function
|
||||
PERFORM fill_matrix USING gv_count 1 1 CHANGING gt_matrix.
|
||||
BREAK-POINT.
|
||||
*&---------------------------------------------------------------------*
|
||||
*& Form FILL_MATRIX
|
||||
*----------------------------------------------------------------------*
|
||||
FORM fill_matrix USING p_count TYPE i
|
||||
p_i TYPE i
|
||||
p_j TYPE i
|
||||
CHANGING p_matrix TYPE gty_t_matrix.
|
||||
|
||||
DATA: lv_i TYPE i,
|
||||
lv_j TYPE i,
|
||||
lv_result TYPE c LENGTH 1,
|
||||
lt_matrix TYPE gty_t_matrix,
|
||||
lv_count TYPE i,
|
||||
lv_value TYPE c.
|
||||
|
||||
lt_matrix[] = p_matrix[].
|
||||
lv_count = p_count.
|
||||
lv_i = p_i.
|
||||
lv_j = p_j.
|
||||
|
||||
WHILE lv_i LE p_number.
|
||||
WHILE lv_j LE p_number.
|
||||
CLEAR lv_result.
|
||||
PERFORM check_position USING lv_i lv_j CHANGING lv_result lt_matrix.
|
||||
IF lv_result NE 'X'.
|
||||
MOVE 'X' TO lv_value.
|
||||
PERFORM get_position USING lv_i lv_j 'U' CHANGING lv_value lt_matrix.
|
||||
ADD 1 TO lv_count.
|
||||
IF lv_count EQ p_number.
|
||||
PERFORM show_matrix USING lt_matrix.
|
||||
ELSE.
|
||||
PERFORM fill_matrix USING lv_count lv_i lv_j CHANGING lt_matrix.
|
||||
ENDIF.
|
||||
lv_value = space.
|
||||
PERFORM get_position USING lv_i lv_j 'U' CHANGING lv_value lt_matrix.
|
||||
SUBTRACT 1 FROM lv_count.
|
||||
ENDIF.
|
||||
ADD 1 TO lv_j.
|
||||
ENDWHILE.
|
||||
ADD 1 TO lv_i.
|
||||
lv_j = 1.
|
||||
ENDWHILE.
|
||||
ENDFORM. " FILL_MATRIX
|
||||
|
||||
*&---------------------------------------------------------------------*
|
||||
*& Form CHECK_POSITION
|
||||
*&---------------------------------------------------------------------*
|
||||
FORM check_position USING value(p_i) TYPE i
|
||||
value(p_j) TYPE i
|
||||
CHANGING p_result TYPE c
|
||||
p_matrix TYPE gty_t_matrix.
|
||||
|
||||
PERFORM get_position USING p_i p_j 'R' CHANGING p_result p_matrix.
|
||||
CHECK p_result NE 'X'.
|
||||
|
||||
PERFORM check_horizontal USING p_i p_j CHANGING p_result p_matrix.
|
||||
CHECK p_result NE 'X'.
|
||||
|
||||
PERFORM check_vertical USING p_i p_j CHANGING p_result p_matrix.
|
||||
CHECK p_result NE 'X'.
|
||||
|
||||
PERFORM check_diagonals USING p_i p_j CHANGING p_result p_matrix.
|
||||
|
||||
ENDFORM. " CHECK_POSITION
|
||||
|
||||
*&---------------------------------------------------------------------*
|
||||
*& Form GET_POSITION
|
||||
*&---------------------------------------------------------------------*
|
||||
FORM get_position USING value(p_i) TYPE i
|
||||
value(p_j) TYPE i
|
||||
value(p_action) TYPE c
|
||||
CHANGING p_result TYPE c
|
||||
p_matrix TYPE gty_t_matrix.
|
||||
|
||||
FIELD-SYMBOLS: <fs_lmatrix> TYPE gty_matrix,
|
||||
<fs_lfield> TYPE any.
|
||||
|
||||
READ TABLE p_matrix ASSIGNING <fs_lmatrix> INDEX p_i.
|
||||
ASSIGN COMPONENT p_j OF STRUCTURE <fs_lmatrix> TO <fs_lfield>.
|
||||
|
||||
CASE p_action.
|
||||
WHEN 'U'.
|
||||
<fs_lfield> = p_result.
|
||||
WHEN 'R'.
|
||||
p_result = <fs_lfield>.
|
||||
WHEN OTHERS.
|
||||
ENDCASE.
|
||||
|
||||
ENDFORM. " GET_POSITION
|
||||
|
||||
*&---------------------------------------------------------------------*
|
||||
*& Form CHECK_HORIZONTAL
|
||||
*&---------------------------------------------------------------------*
|
||||
FORM check_horizontal USING value(p_i) TYPE i
|
||||
value(p_j) TYPE i
|
||||
CHANGING p_result TYPE c
|
||||
p_matrix TYPE gty_t_matrix.
|
||||
DATA: lv_j TYPE i,
|
||||
ls_matrix TYPE gty_matrix.
|
||||
|
||||
FIELD-SYMBOLS <fs> TYPE c.
|
||||
|
||||
lv_j = 1.
|
||||
READ TABLE p_matrix INTO ls_matrix INDEX p_i.
|
||||
WHILE lv_j LE p_number.
|
||||
ASSIGN COMPONENT lv_j OF STRUCTURE ls_matrix TO <fs>.
|
||||
IF <fs> EQ 'X'.
|
||||
p_result = 'X'.
|
||||
RETURN.
|
||||
ENDIF.
|
||||
ADD 1 TO lv_j.
|
||||
ENDWHILE.
|
||||
ENDFORM. " CHECK_HORIZONTAL
|
||||
|
||||
*&---------------------------------------------------------------------*
|
||||
*& Form CHECK_VERTICAL
|
||||
*&---------------------------------------------------------------------*
|
||||
FORM check_vertical USING value(p_i) TYPE i
|
||||
value(p_j) TYPE i
|
||||
CHANGING p_result TYPE c
|
||||
p_matrix TYPE gty_t_matrix.
|
||||
DATA: lv_i TYPE i,
|
||||
ls_matrix TYPE gty_matrix.
|
||||
|
||||
FIELD-SYMBOLS <fs> TYPE c.
|
||||
|
||||
lv_i = 1.
|
||||
WHILE lv_i LE p_number.
|
||||
READ TABLE p_matrix INTO ls_matrix INDEX lv_i.
|
||||
ASSIGN COMPONENT p_j OF STRUCTURE ls_matrix TO <fs>.
|
||||
IF <fs> EQ 'X'.
|
||||
p_result = 'X'.
|
||||
RETURN.
|
||||
ENDIF.
|
||||
ADD 1 TO lv_i.
|
||||
ENDWHILE.
|
||||
ENDFORM. " CHECK_VERTICAL
|
||||
|
||||
*&---------------------------------------------------------------------*
|
||||
*& Form CHECK_DIAGONALS
|
||||
*&---------------------------------------------------------------------*
|
||||
FORM check_diagonals USING value(p_i) TYPE i
|
||||
value(p_j) TYPE i
|
||||
CHANGING p_result TYPE c
|
||||
p_matrix TYPE gty_t_matrix.
|
||||
DATA: lv_dx TYPE i,
|
||||
lv_dy TYPE i.
|
||||
|
||||
* I++ J++ (Up Right)
|
||||
lv_dx = 1.
|
||||
lv_dy = 1.
|
||||
PERFORM check_diagonal USING p_i p_j lv_dx lv_dy CHANGING p_result p_matrix.
|
||||
CHECK p_result NE 'X'.
|
||||
|
||||
* I-- J-- (Left Down)
|
||||
lv_dx = -1.
|
||||
lv_dy = -1.
|
||||
PERFORM check_diagonal USING p_i p_j lv_dx lv_dy CHANGING p_result p_matrix.
|
||||
CHECK p_result NE 'X'.
|
||||
|
||||
* I++ J-- (Right Down)
|
||||
lv_dx = 1.
|
||||
lv_dy = -1.
|
||||
PERFORM check_diagonal USING p_i p_j lv_dx lv_dy CHANGING p_result p_matrix.
|
||||
CHECK p_result NE 'X'.
|
||||
|
||||
* I-- J++ (Left Up)
|
||||
lv_dx = -1.
|
||||
lv_dy = 1.
|
||||
PERFORM check_diagonal USING p_i p_j lv_dx lv_dy CHANGING p_result p_matrix.
|
||||
CHECK p_result NE 'X'.
|
||||
ENDFORM. " CHECK_DIAGONALS
|
||||
|
||||
*&---------------------------------------------------------------------*
|
||||
*& Form CHECK_DIAGONAL
|
||||
*&---------------------------------------------------------------------*
|
||||
FORM check_diagonal USING value(p_i) TYPE i
|
||||
value(p_j) TYPE i
|
||||
value(p_dx) TYPE i
|
||||
value(p_dy) TYPE i
|
||||
CHANGING p_result TYPE c
|
||||
p_matrix TYPE gty_t_matrix.
|
||||
DATA: lv_i TYPE i,
|
||||
lv_j TYPE i,
|
||||
ls_matrix TYPE gty_matrix.
|
||||
|
||||
FIELD-SYMBOLS <fs> TYPE c.
|
||||
|
||||
lv_i = p_i.
|
||||
lv_j = p_j.
|
||||
WHILE 1 EQ 1.
|
||||
ADD: p_dx TO lv_i, p_dy TO lv_j.
|
||||
|
||||
IF p_dx EQ 1.
|
||||
IF lv_i GT p_number. EXIT. ENDIF.
|
||||
ELSE.
|
||||
IF lv_i LT 1. EXIT. ENDIF.
|
||||
ENDIF.
|
||||
|
||||
IF p_dy EQ 1.
|
||||
IF lv_j GT p_number. EXIT. ENDIF.
|
||||
ELSE.
|
||||
IF lv_j LT 1. EXIT. ENDIF.
|
||||
ENDIF.
|
||||
|
||||
READ TABLE p_matrix INTO ls_matrix INDEX lv_i.
|
||||
ASSIGN COMPONENT lv_j OF STRUCTURE ls_matrix TO <fs>.
|
||||
IF <fs> EQ 'X'.
|
||||
p_result = 'X'.
|
||||
RETURN.
|
||||
ENDIF.
|
||||
ENDWHILE.
|
||||
ENDFORM. " CHECK_DIAGONAL
|
||||
*&---------------------------------------------------------------------*
|
||||
*& Form SHOW_MATRIX
|
||||
*----------------------------------------------------------------------*
|
||||
FORM show_matrix USING p_matrix TYPE gty_t_matrix.
|
||||
DATA: lt_matrix TYPE gty_t_matrix,
|
||||
lv_j TYPE i VALUE 1,
|
||||
lv_colum TYPE string VALUE '-'.
|
||||
|
||||
FIELD-SYMBOLS: <fs_matrix> TYPE gty_matrix,
|
||||
<fs_field> TYPE c.
|
||||
|
||||
ADD 1 TO gv_solut.
|
||||
|
||||
WRITE:/ 'Solution: ', gv_solut.
|
||||
|
||||
DO p_number TIMES.
|
||||
CONCATENATE lv_colum '----' INTO lv_colum.
|
||||
ENDDO.
|
||||
|
||||
LOOP AT p_matrix ASSIGNING <fs_matrix>.
|
||||
IF sy-tabix EQ 1.
|
||||
WRITE:/ lv_colum.
|
||||
ENDIF.
|
||||
WRITE:/ '|'.
|
||||
DO p_number TIMES.
|
||||
ASSIGN COMPONENT lv_j OF STRUCTURE <fs_matrix> TO <fs_field>.
|
||||
IF <fs_field> EQ space.
|
||||
WRITE: <fs_field> ,'|'.
|
||||
ELSE.
|
||||
WRITE: <fs_field> COLOR 2 HOTSPOT ON,'|'.
|
||||
ENDIF.
|
||||
ADD 1 TO lv_j.
|
||||
ENDDO.
|
||||
lv_j = 1.
|
||||
WRITE: / lv_colum.
|
||||
ENDLOOP.
|
||||
|
||||
SKIP 1.
|
||||
ENDFORM. " SHOW_MATRIX
|
||||
61
Task/N-queens-problem/Bracmat/n-queens-problem.bracmat
Normal file
61
Task/N-queens-problem/Bracmat/n-queens-problem.bracmat
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
( ( printBoard
|
||||
= board M L x y S R row line
|
||||
. :?board
|
||||
& !ups:? [?M
|
||||
& whl
|
||||
' ( !arg:(?x.?y) ?arg
|
||||
& !M:?L
|
||||
& :?row:?line
|
||||
& whl
|
||||
' ( !L+-1:~<0:?L
|
||||
& !x+1:~>!M:?x
|
||||
& "---+" !line:?line
|
||||
& " |" !row:?row
|
||||
)
|
||||
& "---+" !line:?line
|
||||
& " Q |" !row:?row
|
||||
& whl
|
||||
' ( !L+-1:~<0:?L
|
||||
& "---+" !line:?line
|
||||
& " |" !row:?row
|
||||
)
|
||||
& "\n|" !row "\n+" !line !board:?board
|
||||
)
|
||||
& str$("\n+" !line !board)
|
||||
)
|
||||
( queens
|
||||
= hor ver up down ups downs a z A Z x y Q
|
||||
. !arg:(?hor.?ver.?ups.?downs.?Q)
|
||||
& !ver
|
||||
: (
|
||||
& 1+!solutions:?solutions
|
||||
{ Comment the line below if you only want a count. }
|
||||
& out$(str$("\nsolution " !solutions) printBoard$!Q)
|
||||
& ~ { Fail! (and backtrack to find more solutions)}
|
||||
| #%?y
|
||||
( ?z
|
||||
& !hor
|
||||
: ?A
|
||||
#%?x
|
||||
( ?Z
|
||||
& !x+!y:?up
|
||||
& !x+-1*!y:?down
|
||||
& ~(!ups:? !up ?)
|
||||
& ~(!downs:? !down ?)
|
||||
& queens
|
||||
$ ( !A !Z
|
||||
. !z
|
||||
. !up !ups
|
||||
. !down !downs
|
||||
. (!x.!y) !Q
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
& 0:?solutions
|
||||
& 1 2 3 4 5 6 7 8:?H:?V {You can edit this line to find solutions for other sizes.}
|
||||
& ( queens$(!H.!V...)
|
||||
| out$(found !solutions solutions)
|
||||
)
|
||||
);
|
||||
|
|
@ -1,100 +1,103 @@
|
|||
#include <windows.h>
|
||||
// Much shorter than the version below;
|
||||
// uses C++11 threads to parallelize the computation; also uses backtracking
|
||||
// Outputs all solutions for any table size
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <thread>
|
||||
#include <future>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
using namespace std;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class point
|
||||
// Print table. 'pos' is a vector of positions – the index in pos is the row,
|
||||
// and the number at that index is the column where the queen is placed.
|
||||
static void print(const std::vector<int> &pos)
|
||||
{
|
||||
public:
|
||||
int x, y;
|
||||
point(){ x = y = 0; }
|
||||
void set( int a, int b ){ x = a; y = b; }
|
||||
};
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class nQueens
|
||||
{
|
||||
public:
|
||||
void solve( int c )
|
||||
{
|
||||
_count = c; int len = ( c + 1 ) * ( c + 1 ); _queens = new bool[len]; memset( _queens, 0, len );
|
||||
_cl = new bool[c]; memset( _cl, 0, c ); _ln = new bool[c]; memset( _ln, 0, c );
|
||||
point pt; pt.set( rand() % c, rand() % c ); putQueens( pt, c ); displayBoard();
|
||||
delete [] _queens; delete [] _ln; delete [] _cl;
|
||||
}
|
||||
|
||||
private:
|
||||
void displayBoard()
|
||||
{
|
||||
system( "cls" ); string t = "+---+", q = "| Q |", s = "| |";
|
||||
COORD c = { 0, 0 }; HANDLE h = GetStdHandle( STD_OUTPUT_HANDLE );
|
||||
for( int y = 0, cy = 0; y < _count; y++ )
|
||||
{
|
||||
int yy = y * _count;
|
||||
for( int x = 0; x < _count; x++ )
|
||||
{
|
||||
SetConsoleCursorPosition( h, c ); cout << t;
|
||||
c.Y++; SetConsoleCursorPosition( h, c );
|
||||
if( _queens[x + yy] ) cout << q; else cout << s;
|
||||
c.Y++; SetConsoleCursorPosition( h, c );
|
||||
cout << t; c.Y = cy; c.X += 4;
|
||||
}
|
||||
cy += 2; c.X = 0; c.Y = cy;
|
||||
}
|
||||
}
|
||||
|
||||
bool checkD( int x, int y, int a, int b )
|
||||
{
|
||||
if( x < 0 || y < 0 || x >= _count || y >= _count ) return true;
|
||||
if( _queens[x + y * _count] ) return false;
|
||||
if( checkD( x + a, y + b, a, b ) ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool check( int x, int y )
|
||||
{
|
||||
if( _ln[y] || _cl[x] ) return false;
|
||||
if( !checkD( x, y, -1, -1 ) ) return false;
|
||||
if( !checkD( x, y, 1, -1 ) ) return false;
|
||||
if( !checkD( x, y, -1, 1 ) ) return false;
|
||||
if( !checkD( x, y, 1, 1 ) ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool putQueens( point pt, int cnt )
|
||||
{
|
||||
int it = _count;
|
||||
while( it )
|
||||
{
|
||||
if( !cnt ) return true;
|
||||
if( check( pt.x, pt.y ) )
|
||||
{
|
||||
_queens[pt.x + pt.y * _count] = _cl[pt.x] = _ln[pt.y] = true;
|
||||
point tmp = pt; if( ++tmp.x >= _count ) tmp.x = 0; if( ++tmp.y >= _count ) tmp.y = 0;
|
||||
if( putQueens( tmp, cnt - 1 ) ) return true;
|
||||
_queens[pt.x + pt.y * _count] = _cl[pt.x] = _ln[pt.y] = false;
|
||||
}
|
||||
if( ++pt.x >= _count ) pt.x = 0;
|
||||
it--;
|
||||
// print table header
|
||||
for (int i = 0; i < pos.size(); i++) {
|
||||
std::cout << std::setw(3) << char('a' + i);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int _count;
|
||||
bool* _queens, *_ln, *_cl;
|
||||
};
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
nQueens n; int nq;
|
||||
while( true )
|
||||
{
|
||||
system( "cls" ); cout << "Enter board size bigger than 3 (0 - 3 to QUIT): "; cin >> nq;
|
||||
if( nq < 4 ) return 0; n.solve( nq ); cout << endl << endl;
|
||||
system( "pause" );
|
||||
}
|
||||
return 0;
|
||||
std::cout << '\n';
|
||||
|
||||
for (int row = 0; row < pos.size(); row++) {
|
||||
int col = pos[row];
|
||||
std::cout << row + 1 << std::setw(3 * col + 3) << " # ";
|
||||
std::cout << '\n';
|
||||
}
|
||||
|
||||
std::cout << "\n\n";
|
||||
}
|
||||
|
||||
static bool threatens(int row_a, int col_a, int row_b, int col_b)
|
||||
{
|
||||
return row_a == row_b // same row
|
||||
or col_a == col_b // same column
|
||||
or std::abs(row_a - row_b) == std::abs(col_a - col_b); // diagonal
|
||||
}
|
||||
|
||||
// the i-th queen is in the i-th row
|
||||
// we only check rows up to end_idx
|
||||
// so that the same function can be used for backtracking and checking the final solution
|
||||
static bool good(const std::vector<int> &pos, int end_idx)
|
||||
{
|
||||
for (int row_a = 0; row_a < end_idx; row_a++) {
|
||||
for (int row_b = row_a + 1; row_b < end_idx; row_b++) {
|
||||
int col_a = pos[row_a];
|
||||
int col_b = pos[row_b];
|
||||
if (threatens(row_a, col_a, row_b, col_b)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::mutex print_count_mutex; // mutex protecting 'n_sols'
|
||||
static int n_sols = 0; // number of solutions
|
||||
|
||||
// recursive DFS backtracking solver
|
||||
static void n_queens(std::vector<int> &pos, int index)
|
||||
{
|
||||
// if we have placed a queen in each row (i. e. we are at a leaf of the search tree), check solution and return
|
||||
if (index >= pos.size()) {
|
||||
if (good(pos, index)) {
|
||||
std::lock_guard<std::mutex> lock(print_count_mutex);
|
||||
print(pos);
|
||||
n_sols++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// backtracking step
|
||||
if (not good(pos, index)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// optimization: the first level of the search tree is parallelized
|
||||
if (index == 0) {
|
||||
std::vector<std::future<void>> fts;
|
||||
for (int col = 0; col < pos.size(); col++) {
|
||||
pos[index] = col;
|
||||
auto ft = std::async(std::launch::async, [=]{ auto cpos(pos); n_queens(cpos, index + 1); });
|
||||
fts.push_back(std::move(ft));
|
||||
}
|
||||
|
||||
for (const auto &ft : fts) {
|
||||
ft.wait();
|
||||
}
|
||||
} else { // deeper levels are not
|
||||
for (int col = 0; col < pos.size(); col++) {
|
||||
pos[index] = col;
|
||||
n_queens(pos, index + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::vector<int> start(12); // 12: table size
|
||||
n_queens(start, 0);
|
||||
std::cout << n_sols << " solutions found.\n";
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,88 +1,257 @@
|
|||
#include <windows.h>
|
||||
// A straight-forward brute-force C++ version with formatted output,
|
||||
// eschewing obfuscation and C-isms, producing ALL solutions, which
|
||||
// works on any OS with a text terminal.
|
||||
//
|
||||
// Two basic optimizations are applied:
|
||||
//
|
||||
// It uses backtracking to only construct potentially valid solutions.
|
||||
//
|
||||
// It only computes half the solutions by brute -- once we get the
|
||||
// queen halfway across the top row, any remaining solutions must be
|
||||
// reflections of the ones already computed.
|
||||
//
|
||||
// This is a bare-bones example, without any progress feedback or output
|
||||
// formatting controls, which a more complete program might provide.
|
||||
//
|
||||
// Beware that computing anything larger than N=14 might take a while.
|
||||
// (Time gets exponentially worse the higher the number.)
|
||||
|
||||
// Copyright 2014 Michael Thomas Greer
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// http://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <algorithm>
|
||||
#include <ciso646>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
using namespace std;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
typedef unsigned int uint;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class nQueens_Heuristic
|
||||
// ///////////////////////////////////////////////////////////////////////////
|
||||
struct queens
|
||||
/////////////////////////////////////////////////////////////////////////// //
|
||||
{
|
||||
public:
|
||||
void solve( uint n ) { makeList( n ); drawBoard( n ); }
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
void drawBoard( uint n )
|
||||
// A row or column index. (May be signed or unsigned.)
|
||||
//
|
||||
typedef signed char index_type;
|
||||
|
||||
// A 'solution' is a row --> column lookup of queens on the board.
|
||||
//
|
||||
// It has lexicographical order and can be transformed with a variety of
|
||||
// reflections, which, when properly combined, produce all possible
|
||||
// orientations of a solution.
|
||||
//
|
||||
struct solution_type: std::vector <index_type>
|
||||
{
|
||||
typedef std::vector <index_type> base_type;
|
||||
|
||||
// constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
solution_type( std::size_t N ): base_type( N, -1 ) { }
|
||||
solution_type( const solution_type& s ): base_type( s ) { }
|
||||
|
||||
// compare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
bool operator < ( const solution_type& s ) const
|
||||
{
|
||||
system( "cls" ); string t = "+---+", q = "| Q |", s = "| |";
|
||||
COORD c = { 0, 0 }; HANDLE h = GetStdHandle( STD_OUTPUT_HANDLE );
|
||||
uint w = 0;
|
||||
for( uint y = 0, cy = 0; y < n; y++ )
|
||||
{
|
||||
for( uint x = 0; x < n; x++ )
|
||||
{
|
||||
SetConsoleCursorPosition( h, c ); cout << t;
|
||||
c.Y++; SetConsoleCursorPosition( h, c );
|
||||
if( x + 1 == solution[w] ) cout << q; else cout << s;
|
||||
c.Y++; SetConsoleCursorPosition( h, c );
|
||||
cout << t; c.Y = cy; c.X += 4;
|
||||
}
|
||||
cy += 2; c.X = 0; c.Y = cy; w++;
|
||||
}
|
||||
solution.clear(); odd.clear(); evn.clear();
|
||||
auto mm = std::mismatch( begin(), end(), s.begin() );
|
||||
return (mm.first != end()) and (*mm.first < *mm.second);
|
||||
}
|
||||
|
||||
void makeList( uint n )
|
||||
// transformations . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
void vflip() { std::reverse( begin(), end() ); }
|
||||
|
||||
void hflip() { for (auto& x : *this) x = size() - 1 - x; }
|
||||
|
||||
void transpose()
|
||||
{
|
||||
uint r = n % 6;
|
||||
for( uint x = 1; x <= n; x++ )
|
||||
{
|
||||
if( x & 1 ) odd.push_back( x );
|
||||
else evn.push_back( x );
|
||||
}
|
||||
if( r == 2 )
|
||||
{
|
||||
swap( odd[0], odd[1] );
|
||||
odd.erase( find( odd.begin(), odd.end(), 5 ) );
|
||||
odd.push_back( 5 );
|
||||
}
|
||||
else if( r == 3 )
|
||||
{
|
||||
odd.erase( odd.begin() ); odd.erase( odd.begin() );
|
||||
odd.push_back( 1 ); odd.push_back( 3 );
|
||||
evn.erase( evn.begin() ); evn.push_back( 2 );
|
||||
}
|
||||
vector<uint>::iterator it = evn.begin();
|
||||
while( it != evn.end() )
|
||||
{
|
||||
solution.push_back( ( *it ) );
|
||||
it++;
|
||||
}
|
||||
it = odd.begin();
|
||||
while( it != odd.end() )
|
||||
{
|
||||
solution.push_back( ( *it ) );
|
||||
it++;
|
||||
}
|
||||
solution_type result( size() );
|
||||
for (index_type y = 0; (std::size_t)y < size(); y++)
|
||||
result[ (*this)[ y ] ] = y;
|
||||
swap( result );
|
||||
}
|
||||
};
|
||||
|
||||
// MEMBER VALUES -----------------------------------------------------------
|
||||
|
||||
const int N;
|
||||
std::set <solution_type> solutions;
|
||||
|
||||
// SOLVER ------------------------------------------------------------------
|
||||
|
||||
queens( int N = 8 ):
|
||||
N( (N < 0) ? 0 : N )
|
||||
{
|
||||
// Row by row we create a potentially valid solution.
|
||||
// If a queen can be placed in a valid spot by the time
|
||||
// we get to the last row, then we've found a solution.
|
||||
|
||||
solution_type solution( N );
|
||||
index_type row = 0;
|
||||
while (true)
|
||||
{
|
||||
// Advance the queen along the row
|
||||
++solution[ row ];
|
||||
|
||||
// (If we get past halfway through the first row, we're done.)
|
||||
if ((row == 0) and (solution[ 0 ] > N/2)) break;
|
||||
|
||||
if (solution[ row ] < N)
|
||||
{
|
||||
// If the queen is in a good spot...
|
||||
if (ok( solution, row, solution[ row ] ))
|
||||
{
|
||||
// ...and we're on the last row
|
||||
if (row == N-1)
|
||||
{
|
||||
// Add the solution we found plus all it's reflections
|
||||
solution_type
|
||||
s = solution; solutions.insert( s );
|
||||
s.vflip(); solutions.insert( s );
|
||||
s.hflip(); solutions.insert( s );
|
||||
s.vflip(); solutions.insert( s );
|
||||
s.transpose(); solutions.insert( s );
|
||||
s.vflip(); solutions.insert( s );
|
||||
s.hflip(); solutions.insert( s );
|
||||
s.vflip(); solutions.insert( s );
|
||||
}
|
||||
// otherwise begin marching a queen along the next row
|
||||
else solution[ ++row ] = -1;
|
||||
}
|
||||
|
||||
// When we get to the end of a row's columns then
|
||||
// we need to backup a row and continue from there.
|
||||
}
|
||||
else --row;
|
||||
}
|
||||
}
|
||||
|
||||
// HELPER ------------------------------------------------------------------
|
||||
// This routine helps the solver by identifying column locations
|
||||
// that do not conflict with queens already placed in prior rows.
|
||||
|
||||
bool ok( const solution_type& columns, index_type row, index_type column )
|
||||
{
|
||||
for (index_type r = 0; r < row; r++)
|
||||
{
|
||||
index_type c = columns[ r ];
|
||||
index_type delta_row = row - r;
|
||||
index_type delta_col = (c < column) ? (column - c) : (c - column);
|
||||
|
||||
if ((c == column) or (delta_row == delta_col))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// OUTPUT A SINGLE SOLUTION ------------------------------------------------
|
||||
//
|
||||
// Formatted as (for example):
|
||||
//
|
||||
// d1 b2 g3 c4 f5 h6 e7 a8
|
||||
// Q - - - - - - -
|
||||
// - - - - Q - - -
|
||||
// - - - - - - - Q
|
||||
// - - - - - Q - -
|
||||
// - - Q - - - - -
|
||||
// - - - - - - Q -
|
||||
// - Q - - - - - -
|
||||
// - - - Q - - - -
|
||||
//
|
||||
friend
|
||||
std::ostream&
|
||||
operator << ( std::ostream& outs, const queens::solution_type& solution )
|
||||
{
|
||||
static const char* squares[] = { "- ", "Q " };
|
||||
index_type N = solution.size();
|
||||
|
||||
// Display the queen positions
|
||||
for (auto n = N; n--; )
|
||||
outs << (char)('a' + solution[ n ]) << (N - n) << " ";
|
||||
|
||||
// Display the board
|
||||
for (auto queen : solution)
|
||||
{
|
||||
outs << "\n";
|
||||
for (index_type col = 0; col < N; col++)
|
||||
outs << squares[ col == queen ];
|
||||
}
|
||||
return outs;
|
||||
}
|
||||
|
||||
// OUTPUT ALL SOLUTIONS ----------------------------------------------------
|
||||
//
|
||||
// Display "no solutions" or "N solutions" followed by
|
||||
// each individual solution, separated by blank lines.
|
||||
|
||||
friend
|
||||
std::ostream&
|
||||
operator << ( std::ostream& outs, const queens& q )
|
||||
{
|
||||
if (q.solutions.empty()) outs << "no";
|
||||
else outs << q.solutions.size();
|
||||
outs << " solutions";
|
||||
|
||||
std::size_t n = 1;
|
||||
for (auto solution : q.solutions)
|
||||
{
|
||||
outs << "\n\n#" << n++ << "\n" << solution;
|
||||
}
|
||||
|
||||
vector<uint> odd, evn, solution;
|
||||
return outs;
|
||||
}
|
||||
};
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int main( int argc, char* argv[] )
|
||||
|
||||
|
||||
/* ///////////////////////////////////////////////////////////////////////////
|
||||
string_to <type> ( x )
|
||||
/////////////////////////////////////////////////////////////////////////// */
|
||||
|
||||
template <typename T>
|
||||
T string_to( const std::string& s )
|
||||
{
|
||||
uint n; nQueens_Heuristic nQH;
|
||||
while( true )
|
||||
{
|
||||
cout << "Enter board size bigger than 3 (0 - 3 to QUIT): "; cin >> n;
|
||||
if( n < 4 ) return 0;
|
||||
nQH.solve( n ); cout << endl << endl;
|
||||
}
|
||||
return 0;
|
||||
T result;
|
||||
std::istringstream ss( s );
|
||||
ss >> result;
|
||||
if (!ss.eof()) throw std::runtime_error( "to_string(): invalid conversion" );
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, T default_value>
|
||||
T string_to( const std::string& s )
|
||||
{
|
||||
try { return string_to <T> ( s ); }
|
||||
catch (...) { return default_value; }
|
||||
}
|
||||
|
||||
|
||||
/* ///////////////////////////////////////////////////////////////////////////
|
||||
main program
|
||||
/////////////////////////////////////////////////////////////////////////// */
|
||||
|
||||
int usage( const std::string& name )
|
||||
{
|
||||
std::cerr <<
|
||||
"usage:\n " << name << " 8\n\n"
|
||||
""
|
||||
"Solve the N-Queens problem, brute-force,\n"
|
||||
"and show all solutions for an 8x8 board.\n\n"
|
||||
""
|
||||
"(Specify a value other than 8 for the board size you want.)\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
signed N =
|
||||
(argc < 2) ? 8 :
|
||||
(argc > 2) ? 0 : string_to <signed, 0> ( argv[ 1 ] );
|
||||
|
||||
if (N <= 0) return usage( argv[ 0 ] );
|
||||
|
||||
std::cout << queens( N ) << "\n";
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
100
Task/N-queens-problem/C++/n-queens-problem-3.cpp
Normal file
100
Task/N-queens-problem/C++/n-queens-problem-3.cpp
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
using namespace std;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class point
|
||||
{
|
||||
public:
|
||||
int x, y;
|
||||
point(){ x = y = 0; }
|
||||
void set( int a, int b ){ x = a; y = b; }
|
||||
};
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class nQueens
|
||||
{
|
||||
public:
|
||||
void solve( int c )
|
||||
{
|
||||
_count = c; int len = ( c + 1 ) * ( c + 1 ); _queens = new bool[len]; memset( _queens, 0, len );
|
||||
_cl = new bool[c]; memset( _cl, 0, c ); _ln = new bool[c]; memset( _ln, 0, c );
|
||||
point pt; pt.set( rand() % c, rand() % c ); putQueens( pt, c ); displayBoard();
|
||||
delete [] _queens; delete [] _ln; delete [] _cl;
|
||||
}
|
||||
|
||||
private:
|
||||
void displayBoard()
|
||||
{
|
||||
system( "cls" ); string t = "+---+", q = "| Q |", s = "| |";
|
||||
COORD c = { 0, 0 }; HANDLE h = GetStdHandle( STD_OUTPUT_HANDLE );
|
||||
for( int y = 0, cy = 0; y < _count; y++ )
|
||||
{
|
||||
int yy = y * _count;
|
||||
for( int x = 0; x < _count; x++ )
|
||||
{
|
||||
SetConsoleCursorPosition( h, c ); cout << t;
|
||||
c.Y++; SetConsoleCursorPosition( h, c );
|
||||
if( _queens[x + yy] ) cout << q; else cout << s;
|
||||
c.Y++; SetConsoleCursorPosition( h, c );
|
||||
cout << t; c.Y = cy; c.X += 4;
|
||||
}
|
||||
cy += 2; c.X = 0; c.Y = cy;
|
||||
}
|
||||
}
|
||||
|
||||
bool checkD( int x, int y, int a, int b )
|
||||
{
|
||||
if( x < 0 || y < 0 || x >= _count || y >= _count ) return true;
|
||||
if( _queens[x + y * _count] ) return false;
|
||||
if( checkD( x + a, y + b, a, b ) ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool check( int x, int y )
|
||||
{
|
||||
if( _ln[y] || _cl[x] ) return false;
|
||||
if( !checkD( x, y, -1, -1 ) ) return false;
|
||||
if( !checkD( x, y, 1, -1 ) ) return false;
|
||||
if( !checkD( x, y, -1, 1 ) ) return false;
|
||||
if( !checkD( x, y, 1, 1 ) ) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool putQueens( point pt, int cnt )
|
||||
{
|
||||
int it = _count;
|
||||
while( it )
|
||||
{
|
||||
if( !cnt ) return true;
|
||||
if( check( pt.x, pt.y ) )
|
||||
{
|
||||
_queens[pt.x + pt.y * _count] = _cl[pt.x] = _ln[pt.y] = true;
|
||||
point tmp = pt; if( ++tmp.x >= _count ) tmp.x = 0; if( ++tmp.y >= _count ) tmp.y = 0;
|
||||
if( putQueens( tmp, cnt - 1 ) ) return true;
|
||||
_queens[pt.x + pt.y * _count] = _cl[pt.x] = _ln[pt.y] = false;
|
||||
}
|
||||
if( ++pt.x >= _count ) pt.x = 0;
|
||||
it--;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int _count;
|
||||
bool* _queens, *_ln, *_cl;
|
||||
};
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
nQueens n; int nq;
|
||||
while( true )
|
||||
{
|
||||
system( "cls" ); cout << "Enter board size bigger than 3 (0 - 3 to QUIT): "; cin >> nq;
|
||||
if( nq < 4 ) return 0; n.solve( nq ); cout << endl << endl;
|
||||
system( "pause" );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
88
Task/N-queens-problem/C++/n-queens-problem-4.cpp
Normal file
88
Task/N-queens-problem/C++/n-queens-problem-4.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
using namespace std;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
typedef unsigned int uint;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class nQueens_Heuristic
|
||||
{
|
||||
public:
|
||||
void solve( uint n ) { makeList( n ); drawBoard( n ); }
|
||||
|
||||
private:
|
||||
void drawBoard( uint n )
|
||||
{
|
||||
system( "cls" ); string t = "+---+", q = "| Q |", s = "| |";
|
||||
COORD c = { 0, 0 }; HANDLE h = GetStdHandle( STD_OUTPUT_HANDLE );
|
||||
uint w = 0;
|
||||
for( uint y = 0, cy = 0; y < n; y++ )
|
||||
{
|
||||
for( uint x = 0; x < n; x++ )
|
||||
{
|
||||
SetConsoleCursorPosition( h, c ); cout << t;
|
||||
c.Y++; SetConsoleCursorPosition( h, c );
|
||||
if( x + 1 == solution[w] ) cout << q; else cout << s;
|
||||
c.Y++; SetConsoleCursorPosition( h, c );
|
||||
cout << t; c.Y = cy; c.X += 4;
|
||||
}
|
||||
cy += 2; c.X = 0; c.Y = cy; w++;
|
||||
}
|
||||
solution.clear(); odd.clear(); evn.clear();
|
||||
}
|
||||
|
||||
void makeList( uint n )
|
||||
{
|
||||
uint r = n % 6;
|
||||
for( uint x = 1; x <= n; x++ )
|
||||
{
|
||||
if( x & 1 ) odd.push_back( x );
|
||||
else evn.push_back( x );
|
||||
}
|
||||
if( r == 2 )
|
||||
{
|
||||
swap( odd[0], odd[1] );
|
||||
odd.erase( find( odd.begin(), odd.end(), 5 ) );
|
||||
odd.push_back( 5 );
|
||||
}
|
||||
else if( r == 3 )
|
||||
{
|
||||
odd.erase( odd.begin() ); odd.erase( odd.begin() );
|
||||
odd.push_back( 1 ); odd.push_back( 3 );
|
||||
evn.erase( evn.begin() ); evn.push_back( 2 );
|
||||
}
|
||||
vector<uint>::iterator it = evn.begin();
|
||||
while( it != evn.end() )
|
||||
{
|
||||
solution.push_back( ( *it ) );
|
||||
it++;
|
||||
}
|
||||
it = odd.begin();
|
||||
while( it != odd.end() )
|
||||
{
|
||||
solution.push_back( ( *it ) );
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
vector<uint> odd, evn, solution;
|
||||
};
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
uint n; nQueens_Heuristic nQH;
|
||||
while( true )
|
||||
{
|
||||
cout << "Enter board size bigger than 3 (0 - 3 to QUIT): "; cin >> n;
|
||||
if( n < 4 ) return 0;
|
||||
nQH.solve( n ); cout << endl << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
@ -1,22 +1,19 @@
|
|||
(defun n-queens (n m)
|
||||
(if (= n 1)
|
||||
(loop for x from 1 to m collect (list x))
|
||||
(loop for sol in (n-queens (1- n) m) nconc
|
||||
(loop for col from 1 to m when
|
||||
(loop for row from 0 to (length sol) for c in sol
|
||||
always (and (/= col c)
|
||||
(/= (abs (- c col)) (1+ row)))
|
||||
finally (return (cons col sol)))
|
||||
collect it))))
|
||||
(defun queens (n &optional (m n))
|
||||
(if (zerop n)
|
||||
(list nil)
|
||||
(loop for solution in (queens (1- n) m)
|
||||
nconc (loop for new-col from 1 to m
|
||||
when (loop for row from 1 to n
|
||||
for col in solution
|
||||
always (/= new-col col (+ col row) (- col row)))
|
||||
collect (cons new-col solution)))))
|
||||
|
||||
(defun show-solution (b n)
|
||||
(loop for i in b do
|
||||
(format t "~{~A~^~}~%"
|
||||
(loop for x from 1 to n collect (if (= x i) "Q " ". "))))
|
||||
(defun print-solution (solution)
|
||||
(loop for queen-col in solution
|
||||
do (loop for col from 1 to (length solution)
|
||||
do (write-char (if (= col queen-col) #\Q #\.)))
|
||||
(terpri))
|
||||
(terpri))
|
||||
|
||||
(let ((i 0) (n 8))
|
||||
(mapc #'(lambda (s)
|
||||
(format t "Solution ~a:~%" (incf i))
|
||||
(show-solution s n))
|
||||
(n-queens n n)))
|
||||
(defun print-queens (n)
|
||||
(mapc #'print-solution (queens n)))
|
||||
|
|
|
|||
19
Task/N-queens-problem/Curry/n-queens-problem-4.curry
Normal file
19
Task/N-queens-problem/Curry/n-queens-problem-4.curry
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import CLPFD
|
||||
import Findall
|
||||
|
||||
queens n qs =
|
||||
qs =:= [_ | _ <- [1..n]]
|
||||
& domain qs 1 (length qs)
|
||||
& allDifferent qs
|
||||
& allSafe qs
|
||||
& labeling [FirstFail] qs
|
||||
|
||||
allSafe [] = success
|
||||
allSafe (q:qs) = safe q qs 1 & allSafe qs
|
||||
|
||||
safe :: Int -> [Int] -> Int -> Success
|
||||
safe _ [] _ = success
|
||||
safe q (q1:qs) p = q /=# q1+#p & q /=# q1-#p & safe q qs (p+#1)
|
||||
|
||||
-- oneSolution = unpack $ queens 8
|
||||
-- allSolutions = findall $ queens 8
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
enum side = 8;
|
||||
__gshared int[side] board;
|
||||
|
||||
bool isUnsafe(in int y) nothrow {
|
||||
bool isUnsafe(in int y) nothrow @nogc {
|
||||
immutable int x = board[y];
|
||||
foreach (immutable i; 1 .. y + 1) {
|
||||
immutable int t = board[y - i];
|
||||
|
|
@ -12,7 +12,7 @@ bool isUnsafe(in int y) nothrow {
|
|||
return false;
|
||||
}
|
||||
|
||||
void showBoard() nothrow {
|
||||
void showBoard() nothrow @nogc {
|
||||
import core.stdc.stdio;
|
||||
|
||||
static int s = 1;
|
||||
|
|
@ -24,7 +24,7 @@ void showBoard() nothrow {
|
|||
}
|
||||
}
|
||||
|
||||
void main() nothrow {
|
||||
void main() nothrow @nogc {
|
||||
int y = 0;
|
||||
board[0] = -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ulong nQueens(in uint nn) pure nothrow
|
||||
ulong nQueens(in uint nn) pure nothrow @nogc @safe
|
||||
in {
|
||||
assert(nn > 0 && nn <= 27,
|
||||
"'side' value must be in 1 .. 27.");
|
||||
|
|
@ -38,7 +38,7 @@ in {
|
|||
// Because !d is often faster than d != n.
|
||||
while (d) {
|
||||
// immutable uint pos = 1U << bits.bsf; // Slower.
|
||||
immutable uint pos = -(cast(int)bits) & bits;
|
||||
immutable uint pos = -int(bits) & bits;
|
||||
|
||||
// Mark bit used. Only put current bits on
|
||||
// stack if not zero, so backtracking will
|
||||
|
|
|
|||
68
Task/N-queens-problem/Eiffel/n-queens-problem.e
Normal file
68
Task/N-queens-problem/Eiffel/n-queens-problem.e
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
class
|
||||
QUEENS
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE}
|
||||
counter: INTEGER
|
||||
|
||||
place_queens(board: ARRAY[INTEGER]; level: INTEGER)
|
||||
local
|
||||
i, j: INTEGER
|
||||
safe: BOOLEAN
|
||||
do
|
||||
if level > board.count
|
||||
then
|
||||
counter := counter + 1
|
||||
else
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i > board.count
|
||||
loop
|
||||
safe := True
|
||||
from
|
||||
j := 1
|
||||
until
|
||||
j = level or not safe
|
||||
loop
|
||||
if (board[j] = i)
|
||||
or (j - level = i - board[j])
|
||||
or (j - level = board[j] - i)
|
||||
then
|
||||
safe := False
|
||||
end
|
||||
j := j + 1
|
||||
end
|
||||
if safe
|
||||
then
|
||||
board[level] := i
|
||||
place_queens(board, level + 1)
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature
|
||||
possible_positions_of_n_queens(n: INTEGER): INTEGER
|
||||
local
|
||||
board: ARRAY[INTEGER]
|
||||
do
|
||||
create board.make_filled (0, 1, n)
|
||||
counter := 0
|
||||
place_queens(board, 1)
|
||||
Result := counter
|
||||
end
|
||||
|
||||
make
|
||||
local
|
||||
n: INTEGER
|
||||
do
|
||||
io.put_string ("Please enter the number of queens: ")
|
||||
io.read_integer
|
||||
n := io.last_integer
|
||||
print("%NPossible number of placings: " + possible_positions_of_n_queens(n).out + "%N")
|
||||
end
|
||||
end
|
||||
|
|
@ -1,122 +1,53 @@
|
|||
program queens
|
||||
use omp_lib
|
||||
!The preceding program implements recursion using arrays, since Fortran 77 does not allow recursive
|
||||
!functions. The same algorithm is much easier to follow in Fortran 90, using the RECURSIVE keyword.
|
||||
!Like previously, the program only counts solutions. It's pretty straightforward to adapt it to print
|
||||
!them too: one has to replace the 'm = m + 1' instruction with a PRINT statement.
|
||||
|
||||
function numq(n)
|
||||
implicit none
|
||||
integer, parameter :: long = selected_int_kind(17)
|
||||
integer, parameter :: l = 18
|
||||
integer :: n, i, j, a(l*l, 2), k, p, q
|
||||
integer(long) :: s, b(l*l)
|
||||
real(kind(1d0)) :: t1, t2
|
||||
|
||||
do n = 6, l
|
||||
k = 0
|
||||
p = n/2
|
||||
q = mod(n, 2)*(p + 1)
|
||||
do i = 1, n
|
||||
do j = 1, n
|
||||
if ((abs(i - j) > 1) .and. ((i <= p) .or. ((i == q) .and. (j < i)))) then
|
||||
k = k + 1
|
||||
a(k, 1) = i
|
||||
a(k, 2) = j
|
||||
end if
|
||||
end do
|
||||
end do
|
||||
s = 0
|
||||
t1 = omp_get_wtime()
|
||||
!$omp parallel do schedule(dynamic)
|
||||
do i = 1, k
|
||||
b(i) = pqueens(n, a(i, 1), a(i, 2))
|
||||
end do
|
||||
!$omp end parallel do
|
||||
t2 = omp_get_wtime()
|
||||
print "(I4, I12, F12.3)", n, 2*sum(b(1:k)), t2 - t1
|
||||
integer :: i, n, m, a(n), numq
|
||||
logical :: up(2*n - 1), down(2*n - 1)
|
||||
do i = 1, n
|
||||
a(i) = i
|
||||
end do
|
||||
|
||||
up = .true.
|
||||
down = .true.
|
||||
m = 0
|
||||
call sub(1)
|
||||
numq = m
|
||||
contains
|
||||
function pqueens(n, k1, k2) result(m)
|
||||
implicit none
|
||||
integer(long) :: m
|
||||
integer, intent(in) :: n, k1, k2
|
||||
integer, parameter :: l = 20
|
||||
integer :: a(l), s(l), u(4*l - 2)
|
||||
integer :: i, j, y, z, p, q, r
|
||||
|
||||
do i = 1, n
|
||||
a(i) = i
|
||||
recursive subroutine sub(i)
|
||||
integer :: i, j, k, p, q, s
|
||||
do k = i, n
|
||||
j = a(k)
|
||||
p = i + j - 1
|
||||
q = i - j + n
|
||||
if(up(p) .and. down(q)) then
|
||||
if(i == n) then
|
||||
m = m + 1
|
||||
else
|
||||
up(p) = .false.
|
||||
down(q) = .false.
|
||||
s = a(i)
|
||||
a(i) = a(k)
|
||||
a(k) = s
|
||||
call sub(i + 1)
|
||||
up(p) = .true.
|
||||
down(q) = .true.
|
||||
s = a(i)
|
||||
a(i) = a(k)
|
||||
a(k) = s
|
||||
end if
|
||||
end if
|
||||
end do
|
||||
end subroutine
|
||||
end function
|
||||
|
||||
do i = 1, 4*n - 2
|
||||
u(i) = 0
|
||||
end do
|
||||
|
||||
m = 0
|
||||
r = 2*n - 1
|
||||
if (k1 == k2) return
|
||||
|
||||
p = 1 - k1 + n
|
||||
q = 1 + k1 - 1
|
||||
if ((u(p) /= 0) .or. (u(q + r) /= 0)) return
|
||||
|
||||
u(p) = 1
|
||||
u(q + r) = 1
|
||||
z = a(1)
|
||||
a(1) = a(k1)
|
||||
a(k1) = z
|
||||
p = 2 - k2 + n
|
||||
q = 2 + k2 - 1
|
||||
if ((u(p) /= 0) .or. (u(q + r) /= 0)) return
|
||||
|
||||
u(p) = 1
|
||||
u(q + r) = 1
|
||||
if (k2 /= 1) then
|
||||
z = a(2)
|
||||
a(2) = a(k2)
|
||||
a(k2) = z
|
||||
else
|
||||
z = a(2)
|
||||
a(2) = a(k1)
|
||||
a(k1) = z
|
||||
end if
|
||||
i = 3
|
||||
go to 40
|
||||
|
||||
30 s(i) = j
|
||||
u(p) = 1
|
||||
u(q + r) = 1
|
||||
i = i + 1
|
||||
40 if (i > n) go to 80
|
||||
|
||||
j = i
|
||||
|
||||
50 z = a(i)
|
||||
y = a(j)
|
||||
p = i - y + n
|
||||
q = i + y - 1
|
||||
a(i) = y
|
||||
a(j) = z
|
||||
if ((u(p) == 0) .and. (u(q + r) == 0)) go to 30
|
||||
|
||||
60 j = j + 1
|
||||
if (j <= n) go to 50
|
||||
|
||||
70 j = j - 1
|
||||
if (j == i) go to 90
|
||||
|
||||
z = a(i)
|
||||
a(i) = a(j)
|
||||
a(j) = z
|
||||
go to 70
|
||||
|
||||
!valid queens position found
|
||||
80 m = m + 1
|
||||
|
||||
90 i = i - 1
|
||||
if (i == 2) return
|
||||
|
||||
p = i - a(i) + n
|
||||
q = i + a(i) - 1
|
||||
j = s(i)
|
||||
u(p) = 0
|
||||
u(q + r) = 0
|
||||
go to 60
|
||||
end function
|
||||
program queens
|
||||
implicit none
|
||||
integer :: numq, n, m
|
||||
do n = 4, 16
|
||||
m = numq(n)
|
||||
print *, n, m
|
||||
end do
|
||||
end program
|
||||
|
|
|
|||
122
Task/N-queens-problem/Fortran/n-queens-problem-4.f
Normal file
122
Task/N-queens-problem/Fortran/n-queens-problem-4.f
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
program queens
|
||||
use omp_lib
|
||||
implicit none
|
||||
integer, parameter :: long = selected_int_kind(17)
|
||||
integer, parameter :: l = 18
|
||||
integer :: n, i, j, a(l*l, 2), k, p, q
|
||||
integer(long) :: s, b(l*l)
|
||||
real(kind(1d0)) :: t1, t2
|
||||
|
||||
do n = 6, l
|
||||
k = 0
|
||||
p = n/2
|
||||
q = mod(n, 2)*(p + 1)
|
||||
do i = 1, n
|
||||
do j = 1, n
|
||||
if ((abs(i - j) > 1) .and. ((i <= p) .or. ((i == q) .and. (j < i)))) then
|
||||
k = k + 1
|
||||
a(k, 1) = i
|
||||
a(k, 2) = j
|
||||
end if
|
||||
end do
|
||||
end do
|
||||
s = 0
|
||||
t1 = omp_get_wtime()
|
||||
!$omp parallel do schedule(dynamic)
|
||||
do i = 1, k
|
||||
b(i) = pqueens(n, a(i, 1), a(i, 2))
|
||||
end do
|
||||
!$omp end parallel do
|
||||
t2 = omp_get_wtime()
|
||||
print "(I4, I12, F12.3)", n, 2*sum(b(1:k)), t2 - t1
|
||||
end do
|
||||
|
||||
contains
|
||||
function pqueens(n, k1, k2) result(m)
|
||||
implicit none
|
||||
integer(long) :: m
|
||||
integer, intent(in) :: n, k1, k2
|
||||
integer, parameter :: l = 20
|
||||
integer :: a(l), s(l), u(4*l - 2)
|
||||
integer :: i, j, y, z, p, q, r
|
||||
|
||||
do i = 1, n
|
||||
a(i) = i
|
||||
end do
|
||||
|
||||
do i = 1, 4*n - 2
|
||||
u(i) = 0
|
||||
end do
|
||||
|
||||
m = 0
|
||||
r = 2*n - 1
|
||||
if (k1 == k2) return
|
||||
|
||||
p = 1 - k1 + n
|
||||
q = 1 + k1 - 1
|
||||
if ((u(p) /= 0) .or. (u(q + r) /= 0)) return
|
||||
|
||||
u(p) = 1
|
||||
u(q + r) = 1
|
||||
z = a(1)
|
||||
a(1) = a(k1)
|
||||
a(k1) = z
|
||||
p = 2 - k2 + n
|
||||
q = 2 + k2 - 1
|
||||
if ((u(p) /= 0) .or. (u(q + r) /= 0)) return
|
||||
|
||||
u(p) = 1
|
||||
u(q + r) = 1
|
||||
if (k2 /= 1) then
|
||||
z = a(2)
|
||||
a(2) = a(k2)
|
||||
a(k2) = z
|
||||
else
|
||||
z = a(2)
|
||||
a(2) = a(k1)
|
||||
a(k1) = z
|
||||
end if
|
||||
i = 3
|
||||
go to 40
|
||||
|
||||
30 s(i) = j
|
||||
u(p) = 1
|
||||
u(q + r) = 1
|
||||
i = i + 1
|
||||
40 if (i > n) go to 80
|
||||
|
||||
j = i
|
||||
|
||||
50 z = a(i)
|
||||
y = a(j)
|
||||
p = i - y + n
|
||||
q = i + y - 1
|
||||
a(i) = y
|
||||
a(j) = z
|
||||
if ((u(p) == 0) .and. (u(q + r) == 0)) go to 30
|
||||
|
||||
60 j = j + 1
|
||||
if (j <= n) go to 50
|
||||
|
||||
70 j = j - 1
|
||||
if (j == i) go to 90
|
||||
|
||||
z = a(i)
|
||||
a(i) = a(j)
|
||||
a(j) = z
|
||||
go to 70
|
||||
|
||||
!valid queens position found
|
||||
80 m = m + 1
|
||||
|
||||
90 i = i - 1
|
||||
if (i == 2) return
|
||||
|
||||
p = i - a(i) + n
|
||||
q = i + a(i) - 1
|
||||
j = s(i)
|
||||
u(p) = 0
|
||||
u(q + r) = 0
|
||||
go to 60
|
||||
end function
|
||||
end program
|
||||
|
|
@ -1,37 +1,78 @@
|
|||
# Quick and dirty solution, checking all permutations without backtracking (thus it's slow)
|
||||
IsSafe := function(a)
|
||||
local n, i, j;
|
||||
n := Length(a);
|
||||
for i in [1 .. n - 1] do
|
||||
for j in [i + 1 .. n] do
|
||||
if AbsInt(a[j] - a[i]) = j - i then
|
||||
return false;
|
||||
NrQueens := function(n)
|
||||
local a, up, down, m, sub;
|
||||
a := [1 .. n];
|
||||
up := ListWithIdenticalEntries(2*n - 1, true);
|
||||
down := ListWithIdenticalEntries(2*n - 1, true);
|
||||
m := 0;
|
||||
sub := function(i)
|
||||
local j, k, p, q;
|
||||
for k in [i .. n] do
|
||||
j := a[k];
|
||||
p := i + j - 1;
|
||||
q := i - j + n;
|
||||
if up[p] and down[q] then
|
||||
if i = n then
|
||||
m := m + 1;
|
||||
else
|
||||
up[p] := false;
|
||||
down[q] := false;
|
||||
a[k] := a[i];
|
||||
a[i] := j;
|
||||
sub(i + 1);
|
||||
up[p] := true;
|
||||
down[q] := true;
|
||||
a[i] := a[k];
|
||||
a[k] := j;
|
||||
fi;
|
||||
fi;
|
||||
od;
|
||||
od;
|
||||
return true;
|
||||
end;
|
||||
sub(1);
|
||||
return m;
|
||||
end;
|
||||
|
||||
Queens := function(n)
|
||||
local p, a, v;
|
||||
local a, up, down, v, sub;
|
||||
a := [1 .. n];
|
||||
up := ListWithIdenticalEntries(2*n - 1, true);
|
||||
down := ListWithIdenticalEntries(2*n - 1, true);
|
||||
v := [];
|
||||
for p in SymmetricGroup(n) do
|
||||
a := List([1 .. n], i -> i^p);
|
||||
if IsSafe(a) then
|
||||
Add(v, a);
|
||||
fi;
|
||||
od;
|
||||
sub := function(i)
|
||||
local j, k, p, q;
|
||||
for k in [i .. n] do
|
||||
j := a[k];
|
||||
p := i + j - 1;
|
||||
q := i - j + n;
|
||||
if up[p] and down[q] then
|
||||
if i = n then
|
||||
Add(v, ShallowCopy(a));
|
||||
else
|
||||
up[p] := false;
|
||||
down[q] := false;
|
||||
a[k] := a[i];
|
||||
a[i] := j;
|
||||
sub(i + 1);
|
||||
up[p] := true;
|
||||
down[q] := true;
|
||||
a[i] := a[k];
|
||||
a[k] := j;
|
||||
fi;
|
||||
fi;
|
||||
od;
|
||||
end;
|
||||
sub(1);
|
||||
return v;
|
||||
end;
|
||||
|
||||
v := Queens(8);;
|
||||
Length(v);
|
||||
PrintArray(PermutationMat(PermListList([1 .. 8], v[1]), 8));
|
||||
[ [ 0, 0, 1, 0, 0, 0, 0, 0 ],
|
||||
[ 0, 0, 0, 0, 0, 1, 0, 0 ],
|
||||
[ 0, 1, 0, 0, 0, 0, 0, 0 ],
|
||||
NrQueens(8);
|
||||
a := Queens(8);;
|
||||
PrintArray(PermutationMat(PermList(a[1]), 8));
|
||||
|
||||
[ [ 1, 0, 0, 0, 0, 0, 0, 0 ],
|
||||
[ 0, 0, 0, 0, 1, 0, 0, 0 ],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 1 ],
|
||||
[ 1, 0, 0, 0, 0, 0, 0, 0 ],
|
||||
[ 0, 0, 0, 0, 0, 1, 0, 0 ],
|
||||
[ 0, 0, 1, 0, 0, 0, 0, 0 ],
|
||||
[ 0, 0, 0, 0, 0, 0, 1, 0 ],
|
||||
[ 0, 1, 0, 0, 0, 0, 0, 0 ],
|
||||
[ 0, 0, 0, 1, 0, 0, 0, 0 ] ]
|
||||
|
|
|
|||
|
|
@ -15,11 +15,10 @@ queens n = map fst $ foldM oneMoreQueen ([],[1..n]) [1..n] where
|
|||
-- given a safe arrangement y of queens in the first i rows, and a list of
|
||||
-- possible choices, "oneMoreQueen y _" returns a list of all the safe
|
||||
-- arrangements of queens in the first (i+1) rows along with remaining choices
|
||||
oneMoreQueen (y,d) _ = [ (x:y, d\\[x]) | x <- d, safe x y]
|
||||
oneMoreQueen (y,d) _ = [(x:y, delete x d) | x <- d, safe x] where
|
||||
|
||||
-- "safe x y" tests whether a queen at column x is safe from previous
|
||||
-- queens as recorded in y
|
||||
safe x y = and [ x /= c && x /= c + n && x /= c - n | (n,c) <- zip [1..] y]
|
||||
-- "safe x" tests whether a queen at column x is safe from previous queens
|
||||
safe x = and [x /= c + n && x /= c - n | (n,c) <- zip [1..] y]
|
||||
|
||||
-- prints what the board looks like for a solution; with an extra newline
|
||||
printSolution y = do
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ main = mapM_ print $ queens 8
|
|||
queens :: Int -> [[Int]]
|
||||
queens n = foldM f [] [1..n]
|
||||
where
|
||||
f qs k = [q:qs | q <- [1..n] \\ qs, q `notDiag` qs]
|
||||
f qs _ = [q:qs | q <- [1..n] \\ qs, q `notDiag` qs]
|
||||
q `notDiag` qs = and [abs (q - qi) /= i | (qi,i) <- qs `zip` [1..]]
|
||||
|
|
|
|||
59
Task/N-queens-problem/MUMPS/n-queens-problem-1.mumps
Normal file
59
Task/N-queens-problem/MUMPS/n-queens-problem-1.mumps
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
Queens New count,flip,row,sol
|
||||
Set sol=0
|
||||
For row(1)=1:1:4 Do try(2) ; Not 8, the other 4 are symmetric...
|
||||
;
|
||||
; Remove symmetric solutions
|
||||
Set sol="" For Set sol=$Order(sol(sol)) Quit:sol="" Do
|
||||
. New xx,yy
|
||||
. Kill sol($Translate(sol,12345678,87654321)) ; Vertical flip
|
||||
. Kill sol($Reverse(sol)) ; Horizontal flip
|
||||
. Set flip="--------" for xx=1:1:8 Do ; Flip over top left to bottom right diagonal
|
||||
. . New nx,ny
|
||||
. . Set yy=$Extract(sol,xx),nx=8+1-xx,ny=8+1-yy
|
||||
. . Set $Extract(flip,ny)=nx
|
||||
. . Quit
|
||||
. Kill sol(flip)
|
||||
. Set flip="--------" for xx=1:1:8 Do ; Flip over top right to bottom left diagonal
|
||||
. . New nx,ny
|
||||
. . Set yy=$Extract(sol,xx),nx=xx,ny=yy
|
||||
. . Set $Extract(flip,ny)=nx
|
||||
. . Quit
|
||||
. Kill sol(flip)
|
||||
. Quit
|
||||
;
|
||||
; Display remaining solutions
|
||||
Set count=0,sol="" For Set sol=$Order(sol(sol)) Quit:sol="" Do Quit:sol=""
|
||||
. New s1,s2,s3,txt,x,y
|
||||
. Set s1=sol,s2=$Order(sol(s1)),s3="" Set:s2'="" s3=$Order(sol(s2))
|
||||
. Set txt="+--+--+--+--+--+--+--+--+"
|
||||
. Write !," ",txt Write:s2'="" " ",txt Write:s3'="" " ",txt
|
||||
. For y=8:-1:1 Do
|
||||
. . Write !,y," |"
|
||||
. . For x=1:1:8 Write $Select($Extract(s1,x)=y:" Q",x+y#2:" ",1:"##"),"|"
|
||||
. . If s2'="" Write " |"
|
||||
. . If s2'="" For x=1:1:8 Write $Select($Extract(s2,x)=y:" Q",x+y#2:" ",1:"##"),"|"
|
||||
. . If s3'="" Write " |"
|
||||
. . If s3'="" For x=1:1:8 Write $Select($Extract(s3,x)=y:" Q",x+y#2:" ",1:"##"),"|"
|
||||
. . Write !," ",txt Write:s2'="" " ",txt Write:s3'="" " ",txt
|
||||
. . Quit
|
||||
. Set txt=" A B C D E F G H"
|
||||
. Write !," ",txt Write:s2'="" " ",txt Write:s3'="" " ",txt Write !
|
||||
. Set sol=s3
|
||||
. Quit
|
||||
Quit
|
||||
try(col) New ok,pcol
|
||||
If col>8 Do Quit
|
||||
. New out,x
|
||||
. Set out="" For x=1:1:8 Set out=out_row(x)
|
||||
. Set sol(out)=1
|
||||
. Quit
|
||||
For row(col)=1:1:8 Do
|
||||
. Set ok=1
|
||||
. For pcol=1:1:col-1 If row(pcol)=row(col) Set ok=0 Quit
|
||||
. Quit:'ok
|
||||
. For pcol=1:1:col-1 If col-pcol=$Translate(row(pcol)-row(col),"-") Set ok=0 Quit
|
||||
. Quit:'ok
|
||||
. Do try(col+1)
|
||||
. Quit
|
||||
Quit
|
||||
Do Queens
|
||||
|
|
@ -1,63 +1,3 @@
|
|||
Queens New count,flip,row,sol
|
||||
Set sol=0
|
||||
For row(1)=1:1:4 Do try(2) ; Not 8, the other 4 are symmetric...
|
||||
;
|
||||
; Remove symmetric solutions
|
||||
Set sol="" For Set sol=$Order(sol(sol)) Quit:sol="" Do
|
||||
. New xx,yy
|
||||
. Kill sol($Translate(sol,12345678,87654321)) ; Vertical flip
|
||||
. Kill sol($Reverse(sol)) ; Horizontal flip
|
||||
. Set flip="--------" for xx=1:1:8 Do ; Flip over top left to bottom right diagonal
|
||||
. . New nx,ny
|
||||
. . Set yy=$Extract(sol,xx),nx=8+1-xx,ny=8+1-yy
|
||||
. . Set $Extract(flip,ny)=nx
|
||||
. . Quit
|
||||
. Kill sol(flip)
|
||||
. Set flip="--------" for xx=1:1:8 Do ; Flip over top right to bottom left diagonal
|
||||
. . New nx,ny
|
||||
. . Set yy=$Extract(sol,xx),nx=xx,ny=yy
|
||||
. . Set $Extract(flip,ny)=nx
|
||||
. . Quit
|
||||
. Kill sol(flip)
|
||||
. Quit
|
||||
;
|
||||
; Display remaining solutions
|
||||
Set count=0,sol="" For Set sol=$Order(sol(sol)) Quit:sol="" Do Quit:sol=""
|
||||
. New s1,s2,s3,txt,x,y
|
||||
. Set s1=sol,s2=$Order(sol(s1)),s3="" Set:s2'="" s3=$Order(sol(s2))
|
||||
. Set txt="+--+--+--+--+--+--+--+--+"
|
||||
. Write !," ",txt Write:s2'="" " ",txt Write:s3'="" " ",txt
|
||||
. For y=8:-1:1 Do
|
||||
. . Write !,y," |"
|
||||
. . For x=1:1:8 Write $Select($Extract(s1,x)=y:" Q",x+y#2:" ",1:"##"),"|"
|
||||
. . If s2'="" Write " |"
|
||||
. . If s2'="" For x=1:1:8 Write $Select($Extract(s2,x)=y:" Q",x+y#2:" ",1:"##"),"|"
|
||||
. . If s3'="" Write " |"
|
||||
. . If s3'="" For x=1:1:8 Write $Select($Extract(s3,x)=y:" Q",x+y#2:" ",1:"##"),"|"
|
||||
. . Write !," ",txt Write:s2'="" " ",txt Write:s3'="" " ",txt
|
||||
. . Quit
|
||||
. Set txt=" A B C D E F G H"
|
||||
. Write !," ",txt Write:s2'="" " ",txt Write:s3'="" " ",txt Write !
|
||||
. Set sol=s3
|
||||
. Quit
|
||||
Quit
|
||||
try(col) New ok,pcol
|
||||
If col>8 Do Quit
|
||||
. New out,x
|
||||
. Set out="" For x=1:1:8 Set out=out_row(x)
|
||||
. Set sol(out)=1
|
||||
. Quit
|
||||
For row(col)=1:1:8 Do
|
||||
. Set ok=1
|
||||
. For pcol=1:1:col-1 If row(pcol)=row(col) Set ok=0 Quit
|
||||
. Quit:'ok
|
||||
. For pcol=1:1:col-1 If col-pcol=$Translate(row(pcol)-row(col),"-") Set ok=0 Quit
|
||||
. Quit:'ok
|
||||
. Do try(col+1)
|
||||
. Quit
|
||||
Quit
|
||||
Do Queens
|
||||
|
||||
+--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+
|
||||
8 | |##| Q|##| |##| |##| | |##| Q|##| |##| |##| | |##| | Q| |##| |##|
|
||||
+--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+
|
||||
|
|
@ -2,8 +2,8 @@ safe[q_List, n_] :=
|
|||
With[{l = Length@q},
|
||||
Length@Union@q == Length@Union[q + Range@l] ==
|
||||
Length@Union[q - Range@l] == l]
|
||||
nQueen[q_List:{}, n_] :=
|
||||
nQueen[q_List: {}, n_] :=
|
||||
If[safe[q, n],
|
||||
If[Length[q] == n, q,
|
||||
Cases[Flatten[{nQueen[Append[q, #], n]}, 2] & /@ Range[n],
|
||||
Except[{Null} | {}]]], Null]
|
||||
If[Length[q] == n, {q},
|
||||
Cases[nQueen[Append[q, #], n] & /@ Range[n],
|
||||
Except[{Null} | {}], {2}]], Null]
|
||||
|
|
|
|||
44
Task/N-queens-problem/Mathematica/n-queens-problem-4.math
Normal file
44
Task/N-queens-problem/Mathematica/n-queens-problem-4.math
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
dispSol[sol_] := sol /. {1 -> "Q" , 0 -> "-"} // Grid
|
||||
|
||||
solveNqueens[n_] :=
|
||||
Module[{c, m, b, vars}, c = cqueens[n]; m = mqueens[n];
|
||||
vars = mqueens2[n]; b = bqueens[Length[m]];
|
||||
Partition[LinearProgramming[c, m, b, vars, Integers], n]]
|
||||
|
||||
cqueens[n_] := Table[-1, {i, n^2}]
|
||||
|
||||
bqueens[l_] := Table[{1, -1}, {i, l}]
|
||||
|
||||
mqueens2[n_] := Table[{0, 1}, {i, n^2}]
|
||||
|
||||
mqueens[n_] :=
|
||||
Module[{t, t2, t3, t4}, t = mqueensh[n]; t2 = Append[t, mqueensv[n]];
|
||||
t3 = Append[t2, mqueensd[n]]; t4 = Append[t3, mqueensdm[n]];
|
||||
Partition[Flatten[t4], n^2]]
|
||||
|
||||
mqueensh[n_] :=
|
||||
Module[{t}, t = Table[0, {i, n}, {j, n^2}];
|
||||
For[i = 1, i <= n, i++,
|
||||
For[j = 1, j <= n, j++, t[[i, ((i - 1)*n) + j]] = 1]]; t]
|
||||
|
||||
mqueensv[n_] :=
|
||||
Module[{t}, t = Table[0, {i, n}, {j, n^2}];
|
||||
For[i = 1, i <= n, i++,
|
||||
For[j = 1, j <= n, j++, t[[j, ((i - 1)*n) + j]] = 1]]; t]
|
||||
|
||||
mqueensd[n_] :=
|
||||
Module[{t}, t = Table[0, {i, (2*n) - 1}, {j, n^2}];
|
||||
For[k = 2, k <= 2 n, k++,
|
||||
For[i = 1, i <= n, i++,
|
||||
For[j = 1, j <= n, j++,
|
||||
If[i + j == k, t[[k - 1, ((i - 1)*n) + j]] = 1]]]]; t]
|
||||
|
||||
mqueensdm[n_] :=
|
||||
Module[{t}, t = Table[0, {i, Sum[1, {i, 1 - n, n - 1}]}, {j, n^2}];
|
||||
For[k = 1 - n, k <= n - 1, k++,
|
||||
For[i = 1, i <= n, i++,
|
||||
For[j = 1, j <= n, j++,
|
||||
If[i == j - k, t[[k + n, ((i - 1)*n) + j]] = 1]]]]; t]
|
||||
|
||||
|
||||
solveNqueens[8] // dispSol
|
||||
112
Task/N-queens-problem/Pascal/n-queens-problem-2.pascal
Normal file
112
Task/N-queens-problem/Pascal/n-queens-problem-2.pascal
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
program NQueens;
|
||||
{$IFDEF FPC}
|
||||
{$MODE DELPHI}
|
||||
{$OPTIMIZATION ON}{$OPTIMIZATION REGVAR}{$OPTIMIZATION PeepHole}
|
||||
{$OPTIMIZATION CSE}{$OPTIMIZATION ASMCSE}
|
||||
{$ELSE}
|
||||
{$Apptype console}
|
||||
{$ENDIF}
|
||||
|
||||
uses
|
||||
sysutils;// TDatetime
|
||||
const
|
||||
nmax = 17;
|
||||
type
|
||||
{$IFNDEF FPC}
|
||||
NativeInt = longInt;
|
||||
{$ENDIF}
|
||||
//ala Nikolaus Wirth A-1 = H - 8
|
||||
//diagonal left (A1) to rigth (H8)
|
||||
tLR_diagonale = array[-nmax-1..nmax-1] of char;
|
||||
//diagonal right (A8) to left (H1)
|
||||
tRL_diagonale = array[0..2*nmax-2] of char;
|
||||
//up to Col are the used Cols, after that the unused
|
||||
tFreeCol = array[0..nmax-1] of nativeInt;
|
||||
var
|
||||
LR_diagonale:tLR_diagonale;
|
||||
RL_diagonale:tRL_diagonale;
|
||||
//Using pChar, cause it is implicit an array
|
||||
//It is always set to
|
||||
//@LR_diagonale[row] ,@RL_diagonale[row]
|
||||
pLR,pRL : pChar;
|
||||
FreeCol : tFreeCol;
|
||||
i,
|
||||
n : nativeInt;
|
||||
gblCount : nativeUInt;
|
||||
T0,T1 : TdateTime;
|
||||
procedure Solution;
|
||||
var
|
||||
i : NativeInt;
|
||||
begin
|
||||
// Take's a lot of time under DOS/Win32
|
||||
If gblCount AND $FFF = 0 then
|
||||
write(gblCount:10,#8#8#8#8#8#8#8#8#8#8);
|
||||
// IF n< 9 then
|
||||
IF n < 0 then
|
||||
begin
|
||||
For i := 1 to n do
|
||||
write(FreeCol[i]:4);
|
||||
writeln;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SetQueen(Row:nativeInt);
|
||||
var
|
||||
i,Col : nativeInt;
|
||||
begin
|
||||
IF row <= n then
|
||||
begin
|
||||
For i := row to n do
|
||||
begin
|
||||
Col := FreeCol[i];
|
||||
//check diagonals occupied
|
||||
If (ORD(pLR[-Col]) AND ORD(pRL[Col]))<>0 then
|
||||
begin
|
||||
//a "free" position is found
|
||||
//mark it
|
||||
pRL[ Col]:=#0; //RL_Diagonale[ Row +Col] := 0;
|
||||
pLR[-Col]:=#0; //LR_Diagonale[ Row -Col] := 0;
|
||||
//swap FreeRow[Row<->i]
|
||||
FreeCol[i] := FreeCol[Row];
|
||||
//next row
|
||||
inc(pRL);
|
||||
inc(pLR);
|
||||
FreeCol[Row] := Col;
|
||||
// check next row
|
||||
SetQueen(Row+1);
|
||||
//Undo
|
||||
dec(pLR);
|
||||
dec(pRL);
|
||||
FreeCol[Row] := FreeCol[i];
|
||||
FreeCol[i] := Col;
|
||||
pRL[ Col]:=#1;
|
||||
pLR[-Col]:=#1;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
//solution ist found
|
||||
inc(gblCount);
|
||||
//Solution
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
For i := 0 to nmax-1 do
|
||||
FreeCol[i] := i;
|
||||
//diagonals filled with True = #1 , something <>0
|
||||
fillchar(LR_Diagonale[low(LR_Diagonale)],sizeof(tLR_Diagonale),#1);
|
||||
fillchar(RL_Diagonale[low(RL_Diagonale)],sizeof(tRL_Diagonale),#1);
|
||||
For n := 1 to nMax do
|
||||
begin
|
||||
t0 := time;
|
||||
pLR:=@LR_Diagonale[0];
|
||||
pRL:=@RL_Diagonale[0];
|
||||
gblCount := 0;
|
||||
SetQueen(1);
|
||||
t1:= time;
|
||||
WriteLn(n:6,gblCount:12,FormatDateTime(' NN:SS.ZZZ',T1-t0),' secs');
|
||||
end;
|
||||
WriteLn('Fertig');
|
||||
end.
|
||||
|
|
@ -1,23 +1,16 @@
|
|||
% 8 queens problem.
|
||||
% q(Row) represents a queen, allocated one per row. No rows ever clash.
|
||||
% The columns are chosen iteratively from available columns held in a
|
||||
% list, reduced with each allocation, so we need never check verticals.
|
||||
% For diagonals, we check prior to allocation whether each newly placed
|
||||
% queen will clash with any of the prior placements. This prevents
|
||||
% most invalid permutations from ever being attempted.
|
||||
can_place(_, []) :- !. % success for empty board
|
||||
can_place(q(R,C),Board) :- % check diagonals against allocated queens
|
||||
member(q(Ra,Ca), Board), abs(Ra-R) =:= abs(Ca-C), !, fail.
|
||||
can_place(_,_). % succeed if no diagonals failed
|
||||
:- initialization(main).
|
||||
|
||||
queens([], [], Board, Board). % found a solution
|
||||
queens([q(R)|Queens], Columns, Board, Solution) :-
|
||||
nth0(_,Columns,C,Free), can_place(q(R,C),Board), % find all solutions
|
||||
queens(Queens,Free,[q(R,C)|Board], Solution). % recursively
|
||||
|
||||
queens :-
|
||||
findall(q(N), between(0,7,N), Queens), findall(N, between(0,7,N), Columns),
|
||||
findall(B, queens(Queens, Columns, [], B), Boards), % backtrack over all
|
||||
length(Boards, Len), writef('%w solutions:\n', [Len]), % Output solutions
|
||||
member(R,Boards), reverse(R,Board), writef(' - %w\n', [Board]), fail.
|
||||
queens.
|
||||
queens(N,Qs) :- bagof(X, between(1,N,X), Xs), place(Xs,[],Qs).
|
||||
|
||||
place(Xs,Qs,Res) :-
|
||||
Xs = [] -> Res = Qs
|
||||
; select(Q,Xs,Ys), not_diag(Q,Qs,1), place(Ys,[Q|Qs],Res)
|
||||
.
|
||||
|
||||
not_diag(_, [] , _).
|
||||
not_diag(Q, [Qh|Qs], D) :-
|
||||
abs(Q - Qh) =\= D, D1 is D + 1, not_diag(Q,Qs,D1).
|
||||
|
||||
|
||||
main :- findall(Qs, (queens(8,Qs), write(Qs), nl), _), halt.
|
||||
|
|
|
|||
23
Task/N-queens-problem/Prolog/n-queens-problem-5.pro
Normal file
23
Task/N-queens-problem/Prolog/n-queens-problem-5.pro
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
% 8 queens problem.
|
||||
% q(Row) represents a queen, allocated one per row. No rows ever clash.
|
||||
% The columns are chosen iteratively from available columns held in a
|
||||
% list, reduced with each allocation, so we need never check verticals.
|
||||
% For diagonals, we check prior to allocation whether each newly placed
|
||||
% queen will clash with any of the prior placements. This prevents
|
||||
% most invalid permutations from ever being attempted.
|
||||
can_place(_, []) :- !. % success for empty board
|
||||
can_place(q(R,C),Board) :- % check diagonals against allocated queens
|
||||
member(q(Ra,Ca), Board), abs(Ra-R) =:= abs(Ca-C), !, fail.
|
||||
can_place(_,_). % succeed if no diagonals failed
|
||||
|
||||
queens([], [], Board, Board). % found a solution
|
||||
queens([q(R)|Queens], Columns, Board, Solution) :-
|
||||
nth0(_,Columns,C,Free), can_place(q(R,C),Board), % find all solutions
|
||||
queens(Queens,Free,[q(R,C)|Board], Solution). % recursively
|
||||
|
||||
queens :-
|
||||
findall(q(N), between(0,7,N), Queens), findall(N, between(0,7,N), Columns),
|
||||
findall(B, queens(Queens, Columns, [], B), Boards), % backtrack over all
|
||||
length(Boards, Len), writef('%w solutions:\n', [Len]), % Output solutions
|
||||
member(R,Boards), reverse(R,Board), writef(' - %w\n', [Board]), fail.
|
||||
queens.
|
||||
20
Task/N-queens-problem/Python/n-queens-problem-5.py
Normal file
20
Task/N-queens-problem/Python/n-queens-problem-5.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
def queens(n):
|
||||
a = list(range(n))
|
||||
up = [True]*(2*n - 1)
|
||||
down = [True]*(2*n - 1)
|
||||
def sub(i):
|
||||
nonlocal a, up, down
|
||||
for k in range(i, n):
|
||||
j = a[k]
|
||||
p = i + j
|
||||
q = i - j + n - 1
|
||||
if up[p] and down[q]:
|
||||
if i == n - 1:
|
||||
yield tuple(a)
|
||||
else:
|
||||
up[p] = down[q] = False
|
||||
a[i], a[k] = a[k], a[i]
|
||||
yield from sub(i + 1)
|
||||
up[p] = down[q] = True
|
||||
a[i], a[k] = a[k], a[i]
|
||||
yield from sub(0)
|
||||
|
|
@ -1,64 +1,51 @@
|
|||
/*REXX program place N queens on a NxN chessboard (the 8 queens problem)*/
|
||||
/*REXX program places N queens on a NxN chessboard; the 8 queens problem*/
|
||||
parse arg N . /*get board size arg (if any). */
|
||||
if N=='' then N=8 /*No argument? Use the default.*/
|
||||
file=1; rank=1; q=0 /*starting place, # of queens. */
|
||||
if N=='' then N=8; if N<1 then call noSol /*No arg? Use the default.*/
|
||||
rank=1; file=1; q=0 /*starting rank & file; # queens.*/
|
||||
@.=0; !=left('', 9* (N<18)) /*define empty board, indentation*/
|
||||
/*═════════════════════════════════════find solution: N queens problem.*/
|
||||
do while q<N /*keep placing queens until done.*/
|
||||
@.file.rank=1 /*place a queen on the chessboard*/
|
||||
do while q<N; @.file.rank=1 /*keep placing queens until done.*/
|
||||
if safe?(file,rank) then do; q=q+1 /*if not being attacked, eureka! */
|
||||
file=1 /*another attempt at file #1, */
|
||||
file=1 /*another attempt at another file*/
|
||||
rank=rank+1 /*and also bump the rank pointer.*/
|
||||
end
|
||||
else do /*¬ safe, so it's a bad placement*/
|
||||
@.file.rank=0 /* So, remove this queen. */
|
||||
file=file+1 /*try the next file then. */
|
||||
|
||||
do while file>N; rank=rank-1
|
||||
if rank==0 then call noSol
|
||||
do j=1 for N
|
||||
if @.j.rank then do; file=j; @.file.rank=0
|
||||
q=q-1; file=j+1
|
||||
leave /*j*/
|
||||
end
|
||||
end /*j*/
|
||||
end /*do while file>N*/
|
||||
end /*else do*/
|
||||
end /*while q<N*/
|
||||
iterate /*go&try another queen placement.*/
|
||||
end /* [↑] found a good Q placement.*/
|
||||
@.file.rank=0 /*not safe, so remove this queen.*/
|
||||
file=file+1 /*So, try the next (higher) file.*/
|
||||
do while file>N; rank=rank-1; if rank==0 then call noSol
|
||||
do j=1 for N; if \@.j.rank then iterate /*occupied?*/
|
||||
file=j; @.file.rank=0; q=q-1; file=j+1; leave /*j*/
|
||||
end /*j*/
|
||||
end /*while file>N*/
|
||||
end /*while q<N*/
|
||||
/*══════════════════════════════════════show chessboard with a solution.*/
|
||||
say 'A solution for' N "queens:"; _ = substr( copies("┼───", N) ,2)
|
||||
say 'A solution for' N "queens:"; _ = substr( copies("┼───", N) ,2)
|
||||
lineT = '┌'_"┐"; say; say ! translate(lineT,'┬',"┼")
|
||||
lineB = '└'_"┘"; lineB = translate(lineB, '┴', "┼")
|
||||
line = '├'_"┤" /*define a line for cell boundry.*/
|
||||
bar = '│' /*kinds: horizonal/vertical/salad*/
|
||||
Bqueen = '░♀░' /*glyph befitting the black queen*/
|
||||
Wqueen = ' ♀ ' /* " " " white " */
|
||||
/*═══════════════════════==══════════════place the queens on chessboard.*/
|
||||
do r=1 for N; if r\==1 then say ! line; _= /*process the rank &*/
|
||||
if 1=='f1'x then do; queenSymbol='Q'; dither='9c'x; end /*for EBCDIC.*/
|
||||
else do; queenSymbol='♀'; dither='b0'x; end /* " ASCII.*/
|
||||
Bqueen = dither||queenSymbol||dither /*glyph befitting the black queen*/
|
||||
Wqueen = ' 'queenSymbol" " /* " " " white " */
|
||||
/*═══════════════════════════════════════show chessboard with the queens*/
|
||||
do r=1 for N; if r\==1 then say ! line; _= /*process the rank &*/
|
||||
do f=1 for N; black=(f+r)//2 /*the file; is it a black square?*/
|
||||
qgylph=Wqueen; if black then Qgylph=Bqueen /*use a black queen.*/
|
||||
Qgylph=Wqueen; if black then Qgylph=Bqueen /*use a black queen.*/
|
||||
/*is it black sqare?*/
|
||||
|
||||
if @.f.r then _=_ || bar || Qgylph /*use the 3-char symbol for queen*/
|
||||
else if black then _=_ || bar'░░░' /*¼ dithering char. */
|
||||
else _=_ || bar' ' /*three blanks. */
|
||||
else if black then _=_||bar||copies(dither,3) /*dithering.*/
|
||||
else _=_||bar' ' /*3 blanks. */
|
||||
end /*f*/ /* [↑] preserve square chessboard*/
|
||||
say ! _ || bar
|
||||
say ! _ || bar /*show a rank of the chessboard. */
|
||||
end /*r*/ /*80 cols can view 19x19 chessbrd*/
|
||||
say ! lineB; say /*show last line, + a blank line.*/
|
||||
exit 1 /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────NOSOL subroutine────────────────────*/
|
||||
noSol: say "No solution for" N 'queens.'; exit 0
|
||||
/*──────────────────────────────────SAFE? subroutine────────────────────*/
|
||||
safe?: procedure expose @.; parse arg file,rank
|
||||
do k=rank-1 to 1 by -1; if @.file.k then return 0
|
||||
end
|
||||
f=file-1; r=rank-1
|
||||
do while f\==0 & r\==0; if @.f.r then return 0
|
||||
f=f-1; r=r-1
|
||||
end
|
||||
f=file+1; r=rank-1
|
||||
do while f<=n & r\==0; if @.f.r then return 0
|
||||
f=f+1; r=r-1
|
||||
end
|
||||
safe?: procedure expose @. N; parse arg f,r; rm=r-1; fm=f-1; fp=f+1
|
||||
do k=1 for rm; if @.f.k then return 0; end
|
||||
f=fm; do k=rm by -1 for rm while f\==0; if @.f.k then return 0; f=f-1; end
|
||||
f=fp; do k=rm by -1 for rm while f <=N; if @.f.k then return 0; f=f+1; end
|
||||
return 1
|
||||
|
|
|
|||
|
|
@ -11,91 +11,7 @@
|
|||
;(list (Q 7 4) (Q 6 1) (Q 5 3) (Q 4 6) (Q 3 2) (Q 2 7) (Q 1 5) (Q 0 0))
|
||||
;(list (Q 7 2) (Q 6 4) (Q 5 1) (Q 4 7) (Q 3 5) (Q 2 3) (Q 1 6) (Q 0 0))
|
||||
;(list (Q 7 2) (Q 6 5) (Q 5 3) (Q 4 1) (Q 3 7) (Q 2 4) (Q 1 6) (Q 0 0))
|
||||
;(list (Q 7 4) (Q 6 6) (Q 5 0) (Q 4 2) (Q 3 7) (Q 2 5) (Q 1 3) (Q 0 1))
|
||||
;(list (Q 7 3) (Q 6 5) (Q 5 7) (Q 4 2) (Q 3 0) (Q 2 6) (Q 1 4) (Q 0 1))
|
||||
;(list (Q 7 2) (Q 6 5) (Q 5 7) (Q 4 0) (Q 3 3) (Q 2 6) (Q 1 4) (Q 0 1))
|
||||
;(list (Q 7 4) (Q 6 2) (Q 5 7) (Q 4 3) (Q 3 6) (Q 2 0) (Q 1 5) (Q 0 1))
|
||||
;(list (Q 7 4) (Q 6 6) (Q 5 3) (Q 4 0) (Q 3 2) (Q 2 7) (Q 1 5) (Q 0 1))
|
||||
;(list (Q 7 3) (Q 6 0) (Q 5 4) (Q 4 7) (Q 3 5) (Q 2 2) (Q 1 6) (Q 0 1))
|
||||
;(list (Q 7 2) (Q 6 5) (Q 5 3) (Q 4 0) (Q 3 7) (Q 2 4) (Q 1 6) (Q 0 1))
|
||||
;(list (Q 7 3) (Q 6 6) (Q 5 4) (Q 4 2) (Q 3 0) (Q 2 5) (Q 1 7) (Q 0 1))
|
||||
;(list (Q 7 5) (Q 6 3) (Q 5 1) (Q 4 7) (Q 3 4) (Q 2 6) (Q 1 0) (Q 0 2))
|
||||
;(list (Q 7 5) (Q 6 3) (Q 5 6) (Q 4 0) (Q 3 7) (Q 2 1) (Q 1 4) (Q 0 2))
|
||||
;(list (Q 7 0) (Q 6 6) (Q 5 3) (Q 4 5) (Q 3 7) (Q 2 1) (Q 1 4) (Q 0 2))
|
||||
;(list (Q 7 5) (Q 6 7) (Q 5 1) (Q 4 3) (Q 3 0) (Q 2 6) (Q 1 4) (Q 0 2))
|
||||
;(list (Q 7 5) (Q 6 1) (Q 5 6) (Q 4 0) (Q 3 3) (Q 2 7) (Q 1 4) (Q 0 2))
|
||||
;(list (Q 7 3) (Q 6 6) (Q 5 0) (Q 4 7) (Q 3 4) (Q 2 1) (Q 1 5) (Q 0 2))
|
||||
;(list (Q 7 4) (Q 6 7) (Q 5 3) (Q 4 0) (Q 3 6) (Q 2 1) (Q 1 5) (Q 0 2))
|
||||
;(list (Q 7 3) (Q 6 7) (Q 5 0) (Q 4 4) (Q 3 6) (Q 2 1) (Q 1 5) (Q 0 2))
|
||||
;(list (Q 7 1) (Q 6 6) (Q 5 4) (Q 4 7) (Q 3 0) (Q 2 3) (Q 1 5) (Q 0 2))
|
||||
;(list (Q 7 0) (Q 6 6) (Q 5 4) (Q 4 7) (Q 3 1) (Q 2 3) (Q 1 5) (Q 0 2))
|
||||
;(list (Q 7 1) (Q 6 4) (Q 5 6) (Q 4 3) (Q 3 0) (Q 2 7) (Q 1 5) (Q 0 2))
|
||||
;(list (Q 7 3) (Q 6 1) (Q 5 6) (Q 4 4) (Q 3 0) (Q 2 7) (Q 1 5) (Q 0 2))
|
||||
;(list (Q 7 4) (Q 6 6) (Q 5 0) (Q 4 3) (Q 3 1) (Q 2 7) (Q 1 5) (Q 0 2))
|
||||
;(list (Q 7 5) (Q 6 3) (Q 5 0) (Q 4 4) (Q 3 7) (Q 2 1) (Q 1 6) (Q 0 2))
|
||||
;(list (Q 7 4) (Q 6 0) (Q 5 3) (Q 4 5) (Q 3 7) (Q 2 1) (Q 1 6) (Q 0 2))
|
||||
;(list (Q 7 4) (Q 6 1) (Q 5 5) (Q 4 0) (Q 3 6) (Q 2 3) (Q 1 7) (Q 0 2))
|
||||
;(list (Q 7 5) (Q 6 2) (Q 5 6) (Q 4 1) (Q 3 7) (Q 2 4) (Q 1 0) (Q 0 3))
|
||||
;(list (Q 7 1) (Q 6 6) (Q 5 2) (Q 4 5) (Q 3 7) (Q 2 4) (Q 1 0) (Q 0 3))
|
||||
;(list (Q 7 6) (Q 6 2) (Q 5 0) (Q 4 5) (Q 3 7) (Q 2 4) (Q 1 1) (Q 0 3))
|
||||
;(list (Q 7 4) (Q 6 0) (Q 5 7) (Q 4 5) (Q 3 2) (Q 2 6) (Q 1 1) (Q 0 3))
|
||||
;(list (Q 7 0) (Q 6 4) (Q 5 7) (Q 4 5) (Q 3 2) (Q 2 6) (Q 1 1) (Q 0 3))
|
||||
;(list (Q 7 2) (Q 6 5) (Q 5 7) (Q 4 0) (Q 3 4) (Q 2 6) (Q 1 1) (Q 0 3))
|
||||
;(list (Q 7 5) (Q 6 2) (Q 5 0) (Q 4 6) (Q 3 4) (Q 2 7) (Q 1 1) (Q 0 3))
|
||||
;(list (Q 7 6) (Q 6 4) (Q 5 2) (Q 4 0) (Q 3 5) (Q 2 7) (Q 1 1) (Q 0 3))
|
||||
;(list (Q 7 6) (Q 6 2) (Q 5 7) (Q 4 1) (Q 3 4) (Q 2 0) (Q 1 5) (Q 0 3))
|
||||
;(list (Q 7 4) (Q 6 2) (Q 5 0) (Q 4 6) (Q 3 1) (Q 2 7) (Q 1 5) (Q 0 3))
|
||||
;(list (Q 7 1) (Q 6 4) (Q 5 6) (Q 4 0) (Q 3 2) (Q 2 7) (Q 1 5) (Q 0 3))
|
||||
;(list (Q 7 2) (Q 6 5) (Q 5 1) (Q 4 4) (Q 3 7) (Q 2 0) (Q 1 6) (Q 0 3))
|
||||
;(list (Q 7 5) (Q 6 0) (Q 5 4) (Q 4 1) (Q 3 7) (Q 2 2) (Q 1 6) (Q 0 3))
|
||||
;(list (Q 7 7) (Q 6 2) (Q 5 0) (Q 4 5) (Q 3 1) (Q 2 4) (Q 1 6) (Q 0 3))
|
||||
;(list (Q 7 1) (Q 6 7) (Q 5 5) (Q 4 0) (Q 3 2) (Q 2 4) (Q 1 6) (Q 0 3))
|
||||
;(list (Q 7 4) (Q 6 6) (Q 5 1) (Q 4 5) (Q 3 2) (Q 2 0) (Q 1 7) (Q 0 3))
|
||||
;(list (Q 7 2) (Q 6 5) (Q 5 1) (Q 4 6) (Q 3 4) (Q 2 0) (Q 1 7) (Q 0 3))
|
||||
;(list (Q 7 5) (Q 6 1) (Q 5 6) (Q 4 0) (Q 3 2) (Q 2 4) (Q 1 7) (Q 0 3))
|
||||
;(list (Q 7 2) (Q 6 6) (Q 5 1) (Q 4 7) (Q 3 5) (Q 2 3) (Q 1 0) (Q 0 4))
|
||||
;(list (Q 7 5) (Q 6 2) (Q 5 6) (Q 4 1) (Q 3 3) (Q 2 7) (Q 1 0) (Q 0 4))
|
||||
;(list (Q 7 3) (Q 6 1) (Q 5 6) (Q 4 2) (Q 3 5) (Q 2 7) (Q 1 0) (Q 0 4))
|
||||
;(list (Q 7 6) (Q 6 0) (Q 5 2) (Q 4 7) (Q 3 5) (Q 2 3) (Q 1 1) (Q 0 4))
|
||||
;(list (Q 7 0) (Q 6 5) (Q 5 7) (Q 4 2) (Q 3 6) (Q 2 3) (Q 1 1) (Q 0 4))
|
||||
;(list (Q 7 2) (Q 6 7) (Q 5 3) (Q 4 6) (Q 3 0) (Q 2 5) (Q 1 1) (Q 0 4))
|
||||
;(list (Q 7 5) (Q 6 2) (Q 5 6) (Q 4 3) (Q 3 0) (Q 2 7) (Q 1 1) (Q 0 4))
|
||||
;(list (Q 7 6) (Q 6 3) (Q 5 1) (Q 4 7) (Q 3 5) (Q 2 0) (Q 1 2) (Q 0 4))
|
||||
;(list (Q 7 3) (Q 6 5) (Q 5 7) (Q 4 1) (Q 3 6) (Q 2 0) (Q 1 2) (Q 0 4))
|
||||
;(list (Q 7 1) (Q 6 5) (Q 5 0) (Q 4 6) (Q 3 3) (Q 2 7) (Q 1 2) (Q 0 4))
|
||||
;(list (Q 7 1) (Q 6 3) (Q 5 5) (Q 4 7) (Q 3 2) (Q 2 0) (Q 1 6) (Q 0 4))
|
||||
;(list (Q 7 2) (Q 6 5) (Q 5 7) (Q 4 1) (Q 3 3) (Q 2 0) (Q 1 6) (Q 0 4))
|
||||
;(list (Q 7 5) (Q 6 2) (Q 5 0) (Q 4 7) (Q 3 3) (Q 2 1) (Q 1 6) (Q 0 4))
|
||||
;(list (Q 7 7) (Q 6 3) (Q 5 0) (Q 4 2) (Q 3 5) (Q 2 1) (Q 1 6) (Q 0 4))
|
||||
;(list (Q 7 3) (Q 6 7) (Q 5 0) (Q 4 2) (Q 3 5) (Q 2 1) (Q 1 6) (Q 0 4))
|
||||
;(list (Q 7 1) (Q 6 5) (Q 5 7) (Q 4 2) (Q 3 0) (Q 2 3) (Q 1 6) (Q 0 4))
|
||||
;(list (Q 7 6) (Q 6 1) (Q 5 5) (Q 4 2) (Q 3 0) (Q 2 3) (Q 1 7) (Q 0 4))
|
||||
;(list (Q 7 2) (Q 6 5) (Q 5 1) (Q 4 6) (Q 3 0) (Q 2 3) (Q 1 7) (Q 0 4))
|
||||
;(list (Q 7 3) (Q 6 6) (Q 5 2) (Q 4 7) (Q 3 1) (Q 2 4) (Q 1 0) (Q 0 5))
|
||||
;(list (Q 7 3) (Q 6 7) (Q 5 4) (Q 4 2) (Q 3 0) (Q 2 6) (Q 1 1) (Q 0 5))
|
||||
;(list (Q 7 2) (Q 6 4) (Q 5 7) (Q 4 3) (Q 3 0) (Q 2 6) (Q 1 1) (Q 0 5))
|
||||
;(list (Q 7 3) (Q 6 1) (Q 5 7) (Q 4 4) (Q 3 6) (Q 2 0) (Q 1 2) (Q 0 5))
|
||||
;(list (Q 7 4) (Q 6 6) (Q 5 1) (Q 4 3) (Q 3 7) (Q 2 0) (Q 1 2) (Q 0 5))
|
||||
;(list (Q 7 6) (Q 6 3) (Q 5 1) (Q 4 4) (Q 3 7) (Q 2 0) (Q 1 2) (Q 0 5))
|
||||
;(list (Q 7 7) (Q 6 1) (Q 5 3) (Q 4 0) (Q 3 6) (Q 2 4) (Q 1 2) (Q 0 5))
|
||||
;(list (Q 7 6) (Q 6 1) (Q 5 3) (Q 4 0) (Q 3 7) (Q 2 4) (Q 1 2) (Q 0 5))
|
||||
;(list (Q 7 4) (Q 6 0) (Q 5 7) (Q 4 3) (Q 3 1) (Q 2 6) (Q 1 2) (Q 0 5))
|
||||
;(list (Q 7 3) (Q 6 0) (Q 5 4) (Q 4 7) (Q 3 1) (Q 2 6) (Q 1 2) (Q 0 5))
|
||||
;(list (Q 7 4) (Q 6 1) (Q 5 7) (Q 4 0) (Q 3 3) (Q 2 6) (Q 1 2) (Q 0 5))
|
||||
;(list (Q 7 2) (Q 6 6) (Q 5 1) (Q 4 7) (Q 3 4) (Q 2 0) (Q 1 3) (Q 0 5))
|
||||
;(list (Q 7 2) (Q 6 0) (Q 5 6) (Q 4 4) (Q 3 7) (Q 2 1) (Q 1 3) (Q 0 5))
|
||||
;(list (Q 7 7) (Q 6 1) (Q 5 4) (Q 4 2) (Q 3 0) (Q 2 6) (Q 1 3) (Q 0 5))
|
||||
;(list (Q 7 2) (Q 6 4) (Q 5 1) (Q 4 7) (Q 3 0) (Q 2 6) (Q 1 3) (Q 0 5))
|
||||
;(list (Q 7 2) (Q 6 4) (Q 5 6) (Q 4 0) (Q 3 3) (Q 2 1) (Q 1 7) (Q 0 5))
|
||||
;(list (Q 7 4) (Q 6 1) (Q 5 3) (Q 4 5) (Q 3 7) (Q 2 2) (Q 1 0) (Q 0 6))
|
||||
;(list (Q 7 5) (Q 6 2) (Q 5 4) (Q 4 7) (Q 3 0) (Q 2 3) (Q 1 1) (Q 0 6))
|
||||
;(list (Q 7 4) (Q 6 7) (Q 5 3) (Q 4 0) (Q 3 2) (Q 2 5) (Q 1 1) (Q 0 6))
|
||||
;(list (Q 7 3) (Q 6 1) (Q 5 4) (Q 4 7) (Q 3 5) (Q 2 0) (Q 1 2) (Q 0 6))
|
||||
;(list (Q 7 3) (Q 6 5) (Q 5 0) (Q 4 4) (Q 3 1) (Q 2 7) (Q 1 2) (Q 0 6))
|
||||
;(list (Q 7 5) (Q 6 2) (Q 5 0) (Q 4 7) (Q 3 4) (Q 2 1) (Q 1 3) (Q 0 6))
|
||||
;(list (Q 7 4) (Q 6 2) (Q 5 0) (Q 4 5) (Q 3 7) (Q 2 1) (Q 1 3) (Q 0 6))
|
||||
;(list (Q 7 3) (Q 6 1) (Q 5 7) (Q 4 5) (Q 3 0) (Q 2 2) (Q 1 4) (Q 0 6))
|
||||
;(list (Q 7 5) (Q 6 2) (Q 5 4) (Q 4 6) (Q 3 0) (Q 2 3) (Q 1 1) (Q 0 7))
|
||||
...
|
||||
;(list (Q 7 5) (Q 6 3) (Q 5 6) (Q 4 0) (Q 3 2) (Q 2 4) (Q 1 1) (Q 0 7))
|
||||
;(list (Q 7 3) (Q 6 6) (Q 5 4) (Q 4 1) (Q 3 5) (Q 2 0) (Q 1 2) (Q 0 7))
|
||||
;(list (Q 7 4) (Q 6 6) (Q 5 1) (Q 4 5) (Q 3 2) (Q 2 0) (Q 1 3) (Q 0 7))
|
||||
|
|
|
|||
29
Task/N-queens-problem/SQL/n-queens-problem.sql
Normal file
29
Task/N-queens-problem/SQL/n-queens-problem.sql
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
WITH RECURSIVE
|
||||
positions(i) as (
|
||||
VALUES(0)
|
||||
UNION SELECT ALL
|
||||
i+1 FROM positions WHERE i < 63
|
||||
),
|
||||
solutions(board, n_queens) AS (
|
||||
SELECT '----------------------------------------------------------------', cast(0 AS bigint)
|
||||
FROM positions
|
||||
UNION
|
||||
SELECT
|
||||
substr(board, 1, i) || '*' || substr(board, i+2),n_queens + 1 as n_queens
|
||||
FROM positions AS ps, solutions
|
||||
WHERE n_queens < 8
|
||||
AND substr(board,1,i) != '*'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM positions WHERE
|
||||
substr(board,i+1,1) = '*' AND
|
||||
(
|
||||
i % 8 = ps.i %8 OR
|
||||
cast(i / 8 AS INT) = cast(ps.i / 8 AS INT) OR
|
||||
cast(i / 8 AS INT) + (i % 8) = cast(ps.i / 8 AS INT) + (ps.i % 8) OR
|
||||
cast(i / 8 AS INT) - (i % 8) = cast(ps.i / 8 AS INT) - (ps.i % 8)
|
||||
)
|
||||
LIMIT 1
|
||||
)
|
||||
ORDER BY n_queens DESC -- remove this when using Postgres (they don't support ORDER BY in CTEs)
|
||||
)
|
||||
SELECT board,n_queens FROM solutions WHERE n_queens = 8;
|
||||
Loading…
Add table
Add a link
Reference in a new issue