| A | B | C | D | E | F | |
1 | | 44 | 44 | | 66 | | |
2 | 33 | | 52 | | | 49 | |
3 | 96 | | | | 57 | | |
4 | 11 | 6 | | | | 42 | |
5 | 67 | | | | | 12 | |
6 | 4 | 48 | 71 | 62 | 98 | 38 | |
Place the numbers 1 to 36 in the 6x6 grid, in such a way that consecutive numbers cannot be adjacent in any direction (including diagonally), nor can they appear in the same row or column.
Additionally, cells which are diametrically opposite have a difference of +/- 18.
So, for example, if number
2 was in cell
1A then number
20 would be in cell
6F; if it was in
2C then
20 would be in
5D.
The small digits show the sum of the figures in the adjoining horizontal and vertical cells.
The large digits (6 and 12) are starters.
This is similar in principle to
X Marks the Spot
The program does not take into consideration the rules regarding consecutive numbers (adjacency, same row/column), leaving that to manual selection at the end.
DECLARE FUNCTION notExceed! (row!, col!, v!)
DECLARE SUB place (row!, col!)
CLEAR , , 44444
CLS
DIM SHARED b(7, 7)
DIM SHARED sum(7, 7)
DIM SHARED used(36)
b(4, 2) = 6: b(3, 5) = 6 + 18: used(6) = 1: used(6 + 18) = 1
b(5, 6) = 12: b(2, 1) = 12 + 18: used(12) = 1: used(12 + 18) = 1
b(6, 5) = 26: b(1, 2) = 8: used(26) = 1: used(8) = 1
sum(1, 2) = 44
sum(1, 3) = 44
sum(1, 5) = 66
sum(2, 1) = 33
sum(2, 3) = 52
sum(2, 6) = 49
sum(3, 1) = 96
sum(3, 5) = 57
sum(4, 1) = 11
sum(4, 6) = 42
sum(5, 1) = 67
sum(6, 1) = 4
sum(6, 2) = 48
sum(6, 3) = 71
sum(6, 4) = 62
sum(6, 5) = 98
sum(6, 6) = 38
place 6, 1
END
FUNCTION notExceed (row, col, v)
nExc = 1
r = row - 1: c = col: GOSUB checkThis
r = row + 1: c = col: GOSUB checkThis
r = row: c = col - 1: GOSUB checkThis
r = row: c = col + 1: GOSUB checkThis
notExceed = nExc
EXIT FUNCTION
checkThis:
IF sum(r, c) = 0 THEN RETURN
t = b(r - 1, c) + b(r + 1, c) + b(r, c - 1) + b(r, c + 1) + v
IF t > sum(r, c) THEN notExceed = 0: EXIT FUNCTION
valid = 0
IF r - 1 = 0 THEN
valid = valid + 1
ELSE
IF b(r - 1, c) > 0 THEN valid = valid + 1
END IF
IF r + 1 = 7 THEN
valid = valid + 1
ELSE
IF b(r + 1, c) > 0 THEN valid = valid + 1
END IF
IF c - 1 = 0 THEN
valid = valid + 1
ELSE
IF b(r, c - 1) > 0 THEN valid = valid + 1
END IF
IF c + 1 = 7 THEN
valid = valid + 1
ELSE
IF b(r, c + 1) > 0 THEN valid = valid + 1
END IF
IF valid = 3 THEN
IF t <> sum(r, c) THEN notExceed = 0: EXIT FUNCTION
END IF
RETURN
END FUNCTION
SUB place (row, col)
IF b(row, col) > 0 THEN
GOSUB doNext
EXIT SUB
END IF
IF sum(row + 1, col) > 0 THEN
v = sum(row + 1, col) - b(row + 2, col) - b(row + 1, col - 1) - b(row + 1, col + 1)
IF v > 0 AND v < 37 THEN
IF used(v) = 0 THEN
GOSUB useIt
END IF
END IF
EXIT SUB
END IF
FOR v = 1 TO 36
IF row = 6 AND col = 1 THEN
PRINT v;
END IF
IF used(v) = 0 THEN
IF notExceed(row, col, v) THEN
IF notExceed(7 - row, 7 - col, (v + 17) MOD 36 + 1) THEN
GOSUB useIt
END IF
END IF
END IF
NEXT v
EXIT SUB
useIt:
b(row, col) = v
IF v > 18 THEN
b(7 - row, 7 - col) = v - 18: used(v - 18) = 1
ELSE
b(7 - row, 7 - col) = v + 18: used(v + 18) = 1
END IF
used(v) = 1: used((v + 17) MOD 36 + 1) = 1
GOSUB doNext
b(row, col) = 0
b(7 - row, 7 - col) = 0
used(v) = 0
IF v > 18 THEN
used(v - 18) = 0
ELSE
used(v + 18) = 0
END IF
RETURN
doNext:
IF row = 1 AND col = 6 THEN
PRINT
FOR r = 1 TO 6
FOR c = 1 TO 6
PRINT USING "###"; b(r, c);
NEXT
PRINT
NEXT
PRINT
ELSE
c = col + 1: r = row
IF c > 6 THEN c = 1: r = r - 1
place r, c
END IF
RETURN
END SUB
The lack of check for successive numbers being adjacent or in same column/row, resulted in only one extraneous solution, on the right below. The two purported solutions differe only in the reversal of the diagonal from lower left to upper right.
18 8 15 31 21 28 18 8 15 31 21 10
30 11 5 17 7 19 30 11 5 17 25 19
4 34 9 20 24 14 4 34 9 2 24 14
32 6 2 27 16 22 32 6 20 27 16 22
1 25 35 23 29 12 1 7 35 23 29 12
10 3 13 33 26 36 28 3 13 33 26 36
As mentioned, due to the successive-number rules, the one on the left is the real solution.
|
Posted by Charlie
on 2008-01-03 17:47:41 |