Advertisement
Guest User

N-queens problem

a guest
Nov 12th, 2017
285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rexx 4.25 KB | None | 0 0
  1. /*REXX program  places   N   queens on an  NxN  chessboard  (the eight queens problem). */
  2. parse arg N .                                    /*obtain optional argument from the CL.*/
  3. if N=='' | N==","  then N=8                      /*Not specified:  Then use the default.*/
  4. if N<1  then signal nOK                          /*display a message, the board is bad. */
  5. rank=1;   file=1;       #=0                      /*starting rank&file;  #≡number queens.*/
  6. @.=0;     pad=left('', 9* (N<18) )               /*define empty board;  set indentation.*/
  7.                                                  /* [↓]  rank&file ≡ chessboard row&cols*/
  8.   do  while #<N;      @.file.rank=1              /*keep placing queens until we're done.*/
  9.   if ok(file, rank)  then do; #=#+1;      file=1 /*Queen not being attacked? Then eureka*/
  10.                               rank=rank+1        /*use another attempt at another rank. */
  11.                               iterate            /*go and try another queen placement.  */
  12.                           end                    /* [↑]  found a good queen placement.  */
  13.   @.file.rank=0                                  /*It isn't safe.  So remove this queen.*/
  14.   file=file+1                                    /*So, try the next (higher) chess file.*/
  15.               do  while file>N;      rank=rank-1;                if rank==0  then call nOK
  16.                 do j=1  for N;       if \@.j.rank  then iterate              /*¿ocupado?*/
  17.                 @.j.rank=0;  #=#-1;  file=j+1;  leave
  18.                 end  /*j*/
  19.               end    /*while file>N*/
  20.   end                /*while    #<N*/
  21.  
  22. say 'A solution for '    N    " queens:";   g=substr( copies("╬═══",  N)  ,2);         say
  23. say pad  translate('╔'g"╗", '╦', "╬")            /*display the top rank  (of the board).*/
  24. line   = '╠'g"╣";     dither= '▒'                /*define a line (bar) for cell boundry.*/
  25. bar    = '║'    ;     queen = "Q"                /*kinds:  horizontal, vertical, salad. */
  26. Bqueen = dither || queen || dither               /*glyph befitting a black─square queen.*/
  27. Wqueen =        ' 'queen" "                      /*  "       "     " white─square   "   */
  28.  
  29.   do   rank=1  for N;     if rank\==1  then say pad line;    _=  /*display sep for rank.*/
  30.     do file=1  for N;         B = (file+rank) // 2               /*is the square black? */
  31.     Qgylph=Wqueen;        if  B  then Qgylph=Bqueen              /*use a dithered queen.*/
  32.     if @.file.rank then _=_ || bar || Qgylph                     /*3─char queen symbol. */
  33.                    else if B then _=_ || bar || copies(dither,3) /*use dithering for sq.*/
  34.                              else _=_ || bar || copies(' '   ,3) /* "   3 blanks  "   " */
  35.     end   /*file*/                               /* [↑]  preserve square─ish chessboard.*/
  36.   say pad  _ || bar                              /*show a single rank of the chessboard.*/
  37.   end     /*rank*/                               /*80 cols  can view a 19x19 chessboard.*/
  38.  
  39. say pad  translate('╚'g"╝", '╩', "╬")            /*display the last rank (of the board).*/
  40. exit  1                                          /*stick a fork in it,  we're all done. */
  41. /*──────────────────────────────────────────────────────────────────────────────────────*/
  42. nOK: say;      say  "No solution for"      N      'queens.';          say;          exit 0
  43. /*──────────────────────────────────────────────────────────────────────────────────────*/
  44. ok:  parse arg f,r;   fp=f+1;     rm=r-1         /*if return≡0,  then queen isn't safe. */
  45.               do k=1          for rm;                if @.f.k  then return 0;          end
  46.      f=f-1;   do k=rm  by -1  for rm  while f\==0;   if @.f.k  then return 0;  f=f-1;  end
  47.      f=fp;    do k=rm  by -1  for rm  while f <=N;   if @.f.k  then return 0;  f=f+1;  end
  48.      return 1   /*1≡queen is safe. */            /*  ↑↑↑↑↑↑↑↑    is queen under attack? */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement