DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Magic Square Demo

01.13.2006
| 2396 views |
  • submit to reddit
        
REBOL [
    Title:  "Magic Square program"
    Author: "Gregg Irwin"
    Comment: {
        Credit to Bob Kurosaka and Martin Gardener for inspiration.
    }
]

get-size: has [result] [
    print "Enter the size of the square's side."
    print ""
    result: to-integer ask "It must be an odd number larger than 1 : "
    if any [(result < 3) (even? result)] [get-size]
    result
]

edge-guard: does [
    if row < 1    [row: row + side]
    if col > side [col: col - side]
    if row > side [row: row - side]
    if col < 1    [col: col + side]
]

print-square: func [square side] [
    print ["Magic Square, Order " side]
    print ["Each row, col, and Diagonal add up to " side * (side ** 2 + 1) / 2]
    print ""
    repeat row side [
        repeat col side [
            prin [pick square/:row col tab]
        ]
        print ""
    ]
    print ""
]


magic-square: func [/size sz [integer!]] [
    side: either size [sz][get-size]
    row: 1
    col: (side + 1) / 2         ;Locate the starting cell
    square: array/initial reduce [side side] 0
    poke square/:row col 1      ;Initialize the first value

    for i 2 to-integer (side ** 2) 1 [
        row: row - 1
        col: col + 1                  ;Northeast move
        edge-guard
        if 0 <> pick square/:row col [
            row: row + 1              ;otherwise retreat
            col: col - 1
            row: row + 1              ;Break move
            edge-guard
        ]
        poke square/:row col i
    ]
    print-square square side
]


;-- 0 based version --

; print-square: func [square side] [
;     print ["Magic Square, Order " side]
;     print ["Each row, col, and Diagonal add up to " side * (side ** 2 + 1) / 2  - side]
;     print ""
;     repeat row side [
;         repeat col side [
;             prin [pick square/:row col tab]
;         ]
;         print ""
;     ]
;     print ""
; ]
; 
; magic-square: func [/size sz [integer!]] [
;     side: either size [sz][get-size]
;     row: 1
;     col: (side + 1) / 2         ;Locate the starting cell
;     square: array/initial reduce [side side] none
;     poke square/:row col 0      ;Initialize the first value
; 
;     repeat i to-integer (side ** 2) - 1 [
;         row: row - 1
;         col: col + 1                  ;Northeast move
;         edge-guard
;         if none <> pick square/:row col [
;             row: row + 1              ;otherwise retreat
;             col: col - 1
;             row: row + 1              ;Break move
;             edge-guard
;         ]
;         poke square/:row col i
;     ]
;     print-square square side
; ]

;-- End 0 based version --

magic-square
;magic-square/size 5

halt