Newsgroups: comp.lang.prolog,comp.constraints,sci.op-research
Path: cantaloupe.srv.cs.cmu.edu!fs7.ece.cmu.edu!kinky.eng.gtefsd.com!europa.eng.gtefsd.com!howland.reston.ans.net!news.cac.psu.edu!news.pop.psu.edu!ctc.com!news.mic.ucla.edu!news.bc.net!newsserver.sfu.ca!fornax!cs.sfu.ca!hak
From: hak@cs.sfu.ca (Hassan Ait-Kaci)
Subject: Re: Solving Magic Squares
Message-ID: <HAK.95Jan12192119@brie.cs.sfu.ca>
Sender: news@cs.sfu.ca
Organization: School of Computing Science, Simon Fraser University
References: <3ek1hq$dtt@uni4nn.iaf.nl> <3etu2n$cag@gaudi.ac.upc.es>
	<DBP.95Jan11151327@proof.csli.stanford.edu>
	<3f3lg7$sic@barney.cs.city.ac.uk>
Date: 13 Jan 1995 03:21:19 GMT
Lines: 70
Xref: glinda.oz.cs.cmu.edu comp.lang.prolog:12105 comp.constraints:448 sci.op-research:2527

Michael Jampel <jampel@cs.city.ac.uk> wrote:
>David Barker-Plummer <dbp@csli.stanford.edu> wrote:
>>
>>Offerred without proof: for odd-sided squares, place 1 in the middle
>>of the bottom row, and for each n+1 place it in the square at a
>>position two squares above and one to the right of n, wrapping round
>	  ^^^
>>the square where necessary.  If you obtain a collision, i.e. the
>>previous algorithm requires you to use a previously filled square,
>>then place n+1 in the square above n.
>>
>>So,
>>
>> ***       **2     **2     4*2     4*2     4*2     4*2     4*2     492
>> ***  ===> *** ==> 3** ==> 3** ==> 35* ==> 35* ==> 357 ==> 357 ==> 357 
>> *1*       *1*     *1*     *1*     *1*     *16     *16     816     816
>>                    collision               collision
>
>
>For n=5, do not place it two above and one to the right, but 4 above
>and one to the right. In general, perhaps, for a square of n, place it
>n-1 above and 1 to the right. If there is a collision, again put m+1'th
>number directly above m.
>
>Also appears to work for n=7 with a step of 6 up, one to the right.
>
>Why does this work?

Because the most general and correct algorithm is: for odd-sided
squares, place 1 in the middle of row (n+1)/2 [also works if you place 1
in row (n-1)/2] and for each most recently placed n, place n+1 in the
square north-east of n's cell. That is, if n's cell is (i,j), place n+1
in (i-1,j+1). If that cell is already occupied, use the cell reached by
"bouncing" to the north-west of it, that is, (i-2,j). If you fall out of
the square, use modulo arithmetic to wrap around, and keep bouncing the
same way to the north-west as long as necessary.

For example, for n=3:

*** *** 3** 3** 35* 35* 357 357 357
*** **2 **2 4*2 4*2 4*2 4*2 4*2 492
*1* *1* *1* *1* *1* *16 *16 816 816

and for n=5 (using 1,2,3,...,9,a,b,...,n,o,p for single digit numbers in
radix 25 for compact display):

***** ***** ***** 4**** 4**** 4**** 4**** 4**8* 4**8* 4**8* 4**8* 4c*8*
***** ***** ****3 ****3 ****3 ****3 **7*3 **7*3 **7*3 **7*3 b*7*3 b*7*3
***** ***2* ***2* ***2* ***2* *6*2* *6*2* *6*2* *6*2* *6*2* *6*2* *6*2*
**1** **1** **1** **1** **1** **1** **1** **1** **1** a*1** a*1** a*1**
***** ***** ***** ***** *5*** *5*** *5*** *5*** *5**9 *5**9 *5**9 *5**9

4c*8* 4c*8* 4c*8* 4c*8g 4c*8g 4c*8g 4c*8g 4c*8g 4c*8g 4c*8g 4c*8g 4c*8g 4cp8g
b*7*3 b*7*3 b*7*3 b*7*3 b*7*3 b*7*3 b*7*3 b*7k3 b*7k3 b*7k3 b*7k3 bo7k3 bo7k3
*6*2* *6*2* *6*2f *6*2f *6*2f *6*2f *6j2f *6j2f *6j2f *6j2f n6j2f n6j2f n6j2f
a*1** a*1e* a*1e* a*1e* a*1e* ai1e* ai1e* ai1e* ai1e* ai1em ai1em ai1em ai1em
*5d*9 *5d*9 *5d*9 *5d*9 h5d*9 h5d*9 h5d*9 h5d*9 h5dl9 h5dl9 h5dl9 h5dl9 h5dl9

You may also verify that it works for n=7, and all n odd.

The reason David's method worked on n=3 with his "2 above" rule is
because n-2 is equal to 1 modulo 3. The "fix" proposed by Michael hinted
at that by changing the increment to n-1 for sinze n. This, as shown
above need not be, and the same decrement of 1 can always be used for
all sizes because in general n-(n-1) = 1 modulo n. Simple enough...

Cheers,

-hak
--
