All about flooble | fun stuff | Get a free chatterbox | Free JavaScript | Avatars    
perplexus dot info

Home > Games
Non-Attacking Chess Pieces (Posted on 2003-02-27) Difficulty: 4 of 5
Arrange all 8 chess pieces of one set (no pawns) on a 5x6 board so no piece attacks another. Never mind that they're all the same color--it's "friendly fire". Be sure that the two bishops are on opposite-colored squares. There are 6 ways, not counting reflections and rotations.

See The Solution Submitted by Charlie    
Rating: 3.8000 (5 votes)

Comments: ( Back to comment list | You must be logged in to post comments.)
Spoilers (for DJ)--the program | Comment 6 of 12 |
I hadn't put the program that arrived at the solution into the official solution. I've placed it below for anyone (DJ) wishing to compare algorithms. It is unsatisfying in that it does not check for rotations and reflections. They were minimized by placing the queen only in the upper left "quadrant", but as there are an odd number of rows (the alternative arrangement would have had an odd number of columns with the same problem), the queen did have to be placed there, and that leads to solutions 2 and 3 being mirror reflections of one another, so 7 solutions come out though only 6 unique ones exist. An explicit check for mirror images could have been done, but had not.

DECLARE SUB check (n%)
DEFINT A-Z
DIM SHARED hgt, wdth, pcs, soln
hgt = 5: wdth = 6: pcs = 8
CLS

DATA q,k,r,r,b,b,n,n

DIM SHARED p$(pcs)
DIM SHARED pcx(pcs), pcy(pcs)
FOR i = 1 TO pcs
  READ p$(i)
NEXT



OPEN "chsattck.txt" FOR OUTPUT AS #1
CLS
FOR pcx = 1 TO -INT(-wdth / 2)
  pcx(1) = pcx
  IF hgt = wdth THEN lim2 = pcx: ELSE lim2 = -INT(-hgt / 2)
  FOR pcy = 1 TO lim2
    pcy(1) = pcy
    check 2
  NEXT
NEXT pcx
CLOSE

SUB check (n)
FOR pcx = 1 TO wdth
  pcx(n) = pcx
  FOR pcy = 1 TO hgt
    pcy(n) = pcy
    good = 1
    
    FOR i = 1 TO n - 1
      IF p$(n) = p$(i) THEN
        IF pcy < pcy(i) THEN good = 0: EXIT FOR
        IF pcy = pcy(i) AND pcx < pcx(i) THEN good = 0: EXIT FOR
      END IF
      SELECT CASE p$(i)
        CASE \"q\"
          IF ABS(pcx(i) - pcx(n)) = ABS(pcy(i) - pcy(n)) THEN good = 0: EXIT FOR
          IF pcx(i) = pcx(n) OR pcy(i) = pcy(n) THEN good = 0: EXIT FOR
        CASE \"k\"
         IF ABS(pcy(i) - pcy(n)) < 2 AND ABS(pcx(i) - pcx(n)) < 2 THEN good = 0: EXIT FOR
        CASE \"r\"
          IF pcx(i) = pcx(n) THEN good = 0: EXIT FOR
          IF pcy(i) = pcy(n) THEN good = 0: EXIT FOR
        CASE \"b\"
          IF ABS(pcx(i) - pcx(n)) = ABS(pcy(i) - pcy(n)) THEN good = 0: EXIT FOR
        CASE \"n\"
          IF pcx(i) = pcx(n) AND pcy(i) = pcy(n) THEN good = 0: EXIT FOR
          IF ABS(pcx(n) - pcx(i)) = 2 AND ABS(pcy(n) - pcy(i)) = 1 THEN good = 0: EXIT FOR
          IF ABS(pcx(n) - pcx(i)) = 1 AND ABS(pcy(n) - pcy(i)) = 2 THEN good = 0: EXIT FOR
      END SELECT
    NEXT
    IF good THEN
      SELECT CASE p$(n)
        CASE \"q\"
         FOR i = 1 TO n - 1
          IF ABS(pcx(i) - pcx(n)) = ABS(pcy(i) - pcy(n)) THEN good = 0: EXIT FOR
          IF pcx(i) = pcx(n) OR pcy(i) = pcy(n) THEN good = 0: EXIT FOR
         NEXT
        CASE \"k\"
         FOR i = 1 TO n - 1
           IF ABS(pcy(i) - pcy(n)) < 2 AND ABS(pcx(i) - pcx(n)) < 2 THEN good = 0: EXIT FOR
         NEXT
        CASE \"r\"
         FOR i = 1 TO n - 1
          IF pcx(i) = pcx(n) THEN good = 0: EXIT FOR
          IF pcy(i) = pcy(n) THEN good = 0: EXIT FOR
         NEXT
        CASE \"b\"
         FOR i = 1 TO n - 1
          IF ABS(pcx(i) - pcx(n)) = ABS(pcy(i) - pcy(n)) THEN good = 0: EXIT FOR
          IF p$(i) = \"b\" THEN
            parity = pcx(i) + pcx(n) + pcy(i) + pcy(n)
            IF parity / 2 = INT(parity / 2) THEN good = 0: EXIT FOR
          END IF
         NEXT
        CASE \"n\"
         FOR i = 1 TO n - 1
          IF ABS(pcx(n) - pcx(i)) = 2 AND ABS(pcy(n) - pcy(i)) = 1 THEN good = 0: EXIT FOR
          IF ABS(pcx(n) - pcx(i)) = 1 AND ABS(pcy(n) - pcy(i)) = 2 THEN good = 0: EXIT FOR
         NEXT
      END SELECT

      IF good THEN
        IF n < pcs THEN
          check n + 1
        ELSE
          REDIM b$(hgt, wdth)
          FOR i = 1 TO pcs
            b$(pcy(i), pcx(i)) = p$(i)
          NEXT
          FOR i = 1 TO hgt
            FOR j = 1 TO wdth
              LOCATE , j
              IF b$(i, j) > "" THEN
                PRINT #1, UCASE$(b$(i, j));
              ELSE
                PRINT #1, CHR$(249);
              END IF
            NEXT
            PRINT #1,
          NEXT
          soln = soln + 1
          PRINT #1, STRING$(wdth, "-"); soln
        END IF
      END IF
    END IF
  NEXT
NEXT pcx

END SUB


  Posted by Charlie on 2003-08-28 09:09:27
Please log in:
Login:
Password:
Remember me:
Sign up! | Forgot password


Search:
Search body:
Forums (0)
Newest Problems
Random Problem
FAQ | About This Site
Site Statistics
New Comments (3)
Unsolved Problems
Top Rated Problems
This month's top
Most Commented On

Chatterbox:
Copyright © 2002 - 2024 by Animus Pactum Consulting. All rights reserved. Privacy Information