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.
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 |