Magic squares of odd order: Difference between revisions

Added solution for EDSAC
(Added solution for EDSAC)
Line 1,735:
28 2 32 13 36 17 47
10 40 21 44 25 6 29
</pre>
 
=={{header|EDSAC order code}}==
<syntaxhighlight lang="edsac">
[Magic squares of odd order, for Rosetta Code.
EDSAC program, Initial Orders 2.]
 
[The entries in a magic square of side n can be written as n*u + v + 1,
where u and v range independently over 0, ..., n - 1.
Let the cells be labelled by (x, y) coordinates, where
x = column (left = 0), y = row (bottom = 0).
If n is odd then magic squares can be constructed by setting
u = c*x + d*y + h (mod n)
v = e*x + f*y + k (mod n)
where c, d, e, f, h, k are suitable constants.
Define m = (n - 1)/2. The values of c, ..., k for various methods
of construction are as follows:
c, d, e, f, h, k
Bachet: m + 1, m, m + 1, m + 1, m, 0
De la Loubere: 1, 2m, 2, 2m, m, 0
Conway (lozenge): 1, 2m, 1, 1, m, m + 1
Rosetta Code C: 2m, 2m - 1, 1, 2m - 1, 2m - 1, 2m
------------------------------------------------------------------------------]
[Arrange the storage]
T45K P56F [H parameter: subroutine to print string]
T46K P100F [N parameter: subroutine to print number]
T47K P200F [M parameter: main routine + high-level subroutine]
 
[Main routine + non-library subroutine]
E25K TM GK
[Rows are printed in the order y = n - 1 (top) to y = 0 (bottom).
Row y = n is a fictitious row used during initialization.]
[Locations set up by main routine; some are changed by subroutine]
[0] PF [m]
[1] PF [n]
[2] PF [n^2]
[3] PF [n * 2^11]
[4] PF [c, changed to n*(n - c) = dec to n*u on inc(x)]
[5] PF [d, changed to n*d = dec to n*u on dec(y)]
[6] PF [e, changed to n - e = dec to v on inc(x)]
[7] PF [f = dec to v when dec(y)]
[8] PF [h, changed to n*u for start of current row]
[9] PF [k, changed to v for start of current row]
[Locations used only by subroutine]
[10] PF [n*u]
[11] PF [v]
[12] PF [x count]
[13] PF [y count]
 
[Subroutine to print magic square, using parameters set up by main routine.]
[14] A3F T77@ [plant return link as usual]
A80@ T1F [set to print leading zeros as spaces]
A1@ S6@ T6@ [replace e by n - e]
A1@ S4@ T4@ [replace c by n - c]
[Multiply certain values by n. To maintain the integer scaling,
products have to be shifted 16 left before storing.]
H3@ V8@ [acc := (n << 11)*h]
L8F T8@ [shift 5 more left and store n*h]
V5@ L8F T5@ [similarly n*d]
V4@ L8F T4@ [similarly n*(n - c)]
[Loop round rows y := n - 1 down to 0. At the moment y = n.]
S1@ T13@ [initialize negative count of rows (y values)]
[Start of a row. Here acc = 0]
[36] S1@ T12@ [inititialize negative count of columns (x values)]
A8@ S5@ [decrement n*u by n*d]
E42@ [skip if n*u >= 0]
A2@ [else inc n*u by n^2]
[42] U8@ [store updated n*u for next time]
T10@ [also copy to initialize this row]
A9@ S7@ [decrement v by f]
E48@ [skip if v >= 0]
A1@ [else inc v by n]
[48] U9@ [store updated v at for next time]
U11@ [also copy to initialize this row]
[Next column. Here acc = v]
[50] A10@ A78@ TF [cell value v + n*u + 1 to 0F for printing]
[53] A53@ GN [call subroutine to print cell value]
A12@ A78@ [increment negative column count]
E70@ [jump if row is complete]
T12@ [else update count]
A10@ S4@ [dec n*u by n*n - c)]
E63@ [skip if n*U >= 0]
A2@ [else inc n*u by n^2]
[63] T10@ [store updated n*u for next time]
A11@ S6@ [dec v by n - e]
E68@ [skip if v >= 0]
A1@ [else inc v by n]
[68] U11@ [store updated v, keep v in acc]
E50@ [loop back for next cell in row]
[Row finished]
[70] O81@ O82@ [print CR LF]
A13@ A78@ [inc negative row count]
E77@ [exit if done all rows]
T13@ E36@ [else update count and loop back]
[77] ZF [(planted) jump back to caller]
[Constants]
[78] PD [17-bit 1]
[79] K4096F [null]
[80] !F [space]
[81] @F [carriage return]
[82] &F [line feed]
[83] P10F [for testing number of phone pulses]
[Strings for printing. K2048F sets letters mode; K4096F is EDSAC null.]
[84] K2048FMFAFGFIFCF!FSFQFUFAFRFEF!FOFFF!FOFRFDFEFRF!F#FWF*FMF#FZFQF@F&FK4096F
[117] K2048FDFIFAFLF!FMF!F#FKFPF!F*FTFOF!FCFAFNFCFEFLF#FLF@F&FK4096F
[144] K2048FBFAFCFHFEFTF#FCF@F&FK4096F
[156] K2048FDFEF!FLFAF!FLFOFUFBFEFRFEF#FCF@F&FK4096F
[175] K2048FCFOFNFWFAFYF#FCF@F&FK4096F
[187] K2048FRFOFSFEFTFTFAF!FCFOFDFEF!FCF#FCF@F&FK4096F
 
[Enter with acc = 0]
[207] A207@ GH A84@ [print heading]
[210] A210@ GH A117@ [prompt user to dial m, where n = 2m + 1]
ZF [halt program; restarts when user dials]
[Here acc holds number of pulses in address field.
Number of pulses = 10 if user dialled '0', else = number that user dialled.]
S83@ E292@ [test for '0', jump to exit if so]
A83@ [restore acc after test]
L512F [shift m to top 5 bits for printing]
UF [temp to 0F]
OF O81@ O82@ [print digit m, plus CR LF]
R512F [restore m in address field, same as 2m right-justified]
A78@ U1@ [make and store n = 2m + 1, right justified]
RD T@ [make and store m right-justified]
A1@ L512F T3@ [make and store n << 11]
H3@ V1@ [acc := (n << 11)*n]
L8F [shift 5 left for integer scaling]
T2@ [store n^2]
[Bachet's method]
[234] A234@ GH A144@ [print name of method]
A@ U5@ U8@ [d, h := m]
A78@ U4@ U6@ T7@ [c, e, f := m + 1]
T9@ [k := 0]
[245] A245@ G14@ [call s/r to print square]
[De la Loubere's (miscalled Siamese) method]
[247] A247@ GH A156@ [print name of method]
A78@ U4@ [c := 1]
LD T6@ [e := 2]
A@ U8@ [h := m]
LD U5@ T7@ [d, f := 2m]
T9@ [k := 0 ]
[260] A260@ G14@ [call s/r to print square]
[Conway's lozenge method turns out to be of this type]
[262] A262@ GH A175@ [print name of method]
A78@ U4@ U6@ U7@ [c, e, f := 1]
A@ T9@ [k := m + 1]
A@ U8@ [h := m]
LD T5@ [d := 2m]
[275] A275@ G14@ [call s/r to print square]
[C solution on Rosetta Code website]
[277] A277@ GH A187@ [print name of method]
A78@ T6@ [e := 1]
A@ LD U4@ U9@ [c, k := 2m]
S78@ U5@ U7@ T8@ [d, f, h := 2m - 1]
[290] A290@
G14@ [call s/r to print square]
[292] O79@ [done; print null to flush teleprinter buffer]
ZF [halt the machine]
E25K TH
[Subroutine to print a string.
Input: A order for first character must follow subroutine call (G order).
String is terminated with EDSAC null, which is sent to the teleprinter.]
GKA18@U17@S19@T4@AFT6@AFUFOFE12@A20@G16@TFA6@A2FG5@TFZFU3FU1FK2048F
 
E25K TN
[Subroutine to print non-negative 17-bit integer.
Parameters: 0F = integer to be printed (not preserved)
1F = character for leading zero (preserved)
Workspace: 4F..7F, 38 locations]
GKA3FT34@A1FT7FS35@T6FT4#FAFT4FH36@V4FRDA4#FR1024FH37@E23@O7FA2F
T6FT5FV4#FYFL8FT4#FA5FL1024FUFA6FG16@OFTFT7FA6FG17@ZFP4FZ219DTF
 
[================ M parameter again ================]
E25K TM GK
E207Z [define entry point]
PF [acc = 0 on entry]
</syntaxhighlight>
{{out}}
<pre>
MAGIC SQUARE OF ORDER 2M+1
DIAL M (0 TO CANCEL)
2
BACHET:
3 16 9 22 15
20 8 21 14 2
7 25 13 1 19
24 12 5 18 6
11 4 17 10 23
DE LA LOUBERE:
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
CONWAY:
18 24 5 6 12
22 3 9 15 16
1 7 13 19 25
10 11 17 23 4
14 20 21 2 8
ROSETTA CODE C:
2 23 19 15 6
14 10 1 22 18
21 17 13 9 5
8 4 25 16 12
20 11 7 3 24
</pre>
 
113

edits