| model 'rosebush'
! Rosebush.mos : Computes move to safe position (if available)
in game of Rosebushes
! Written by : Martin J. Chlond
! Date written : 6 January 2002
! References : Vajda, S., Mathematical Games and how to play
them (pp 59,59)
! Schuh, F., The Master Book of Mathematical Recreations (*109
pp 141,142)
! Berlekamp, E.R., Conway, J.H., Guy, R.K., Winning Ways for
your Mathematical Plays
uses 'mmxprs'
parameters
heap = 5 ! number of heaps
nmax = 16 ! maximum number allowed in any heap
k = 2 ! maximum number of heaps to change
end-parameters
declarations
! data tables
n: array(1..heap) of real
z: array(1..4) of real
! variables
d: array(1..heap) of mpvar ! 1 if heap changed, 0 otherwise
m: array(1..heap) of mpvar ! number in each heap after move
e: array(1..heap) of mpvar ! 1 if heap odd after move, 0 if
even
b: array(1..heap) of mpvar ! dummy variable for parity check
of heaps
w: array(1..4,1..3) of mpvar ! dummy variables for safety
check
s: mpvar ! decimal equivalent of heap parities
end-declarations
n:=[1,1,2,3,4] ! number in each heap before move (example
from Vajda)
z:=[0,7,19,28] ! decimal equivalents of 'safe' heap parities
(see Vajda)
! minimise number of heaps changed - if solution is zero then
current position already safe
heapch:= sum(i in 1..heap) d(i)
! maximum of k rows to change
maxh:= sum(i in 1..heap) d(i) <= k
! ensures safe position after move
forall(i in 1..4) do
lca(i):= s-(32-z(i))*w(i,1) <= z(i)-1
lcb(i):= s-z(i)*w(i,1) >= 0
lcc(i):= s+(z(i)+1)*w(i,2) >= z(i)+1
lcd(i):= s+31*w(i,2) <= z(i)+31
lce(i):= w(i,3) = w(i,1)+w(i,2)-1
end-do
es:= sum(i in 1..4) w(i,3) = 1
! positions before and after are consistent with move
forall(i in 1..heap)
cons(i):= n(i)-d(i) = m(i)
! e(i) = 1 if m(i) odd, 0 otherwise
forall(i in 1..heap)
eset(i):= m(i) = 2*b(i)+e(i)
! computes decimal equivalent of heap parities
sset:= sum(i in 1..heap) 2^(heap-i)*e(i) = s
! ensures piles remain in increasing order
forall(i in 1..heap-1)
ndec(i):= m(i+1) >= m(i)
forall(i in 1..heap) do
d(i) is_binary
m(i) is_integer
e(i) is_binary
b(i) is_integer
end-do
forall(i in 1..4,j in 1..3)
w(i,j) is_binary
! minimise number of heaps changed - if solution is zero then
current position already safe
minimise( heapch )
! output solution
forall(i in 1..heap) do
write(getsol(d(i)),' ',getsol(m(i)))
writeln
end-do
end-model
|