幻方解法之Strachey法生成单偶幻方

来源:互联网 发布:animate淘宝旗舰店 编辑:程序博客网 时间:2024/04/30 05:06

/*

程序思想参考百度百科上"幻方法则" 2015-01-27

http://baike.baidu.com/link?url=7ynfkLYfGv4f7PtQkuH4PSn_8IFr_QFAN-Bnsk0hmd2uk6WITW7r1d8o7IQJ1IL3bNRHbpHYbVXpDAvNbyJBDK


其实在维基百科上有更全面的,搜索Magic square即可查到,可惜太英语了,有点难,留着以后看^*^


代码环境xcode6.1 playground


几个公用函数只在第一篇显示,后面的篇章不在重复

func isMagic(s:[[Int]])->[Int]?

func printMagic(s:[[Int]])

func signed(aint: Int)->Int

func correction(k: Int, step: Int) ->Int

*/


/*

二、单偶幻方的解法

n阶单偶幻方表示为4m+2阶幻方。将其等分为四分,成为如下图所示ABCD四个2m+1阶奇数幻方。

A C

D B

A1(2m+1)^2填写成(2m+1)阶幻方;B(2m+1)^2+12*(2m+1)^2填写成(2m+1)阶幻方;C2*(2m+1)^2+13*(2m+1)2填写成(2m+1)阶幻方;D3*(2m+1)^2+14*(2m+1)^2填写成(2m+1)阶幻方;

【注:(2m+1)^2(2m+1)的平方,以下同】

8 1 6 26 19 24

3 5 7 21 23 25

4 9 2 22 27 20

35 28 33 17 10 15

30 32 34 12 14 16

31 36 29 13 18 11

[1] A阵中取左侧m列与D阵对应小格对调;在C阵中取右侧m-1列与B阵对应小格对调;最后在A阵中间行取中心格与左侧一格与D阵对应小格对调。

6阶幻方就是4*1+2,那么m就是1。在A中间一行取中心格1个小格,其他行左侧边缘取1个小格,将其与D相应方格内交换;BC接近右侧m-1列相互交换(6阶幻方m-1=0,则不用互换)。如下图用Strachey法生成的6阶幻方:

35 1 6 26 19 24

3 32 7 21 23 25

31 9 2 22 27 20

8 28 33 17 10 15

30 5 34 12 14 16

4 36 29 13 18 11

每一行,每一列,对角线的和值(称为幻和值)为111

一个n阶幻方幻和值公式为:

Nn=1/2xn(n^2+1)

【注:n^2n的平方】

N6=1/2x6x(36+1)=111

*/


func DOStrachey(#subMagic:[[Int]])->([[Int]])?{

   let subStep = subMagic.count

   let step = subStep * 2

    

   let aRow = [Int](count: step, repeatedValue:0)

   var solution = [[Int]](count: step, repeatedValue: aRow)

    

    

    //填充s中一块区域,使之成为幻方,起点为row,col 边长为substep

   func fillSubMagic(inout s:[[Int]], #row0:Int, #col0: Int, #subMagic: [[Int]],var #iPut0:Int){

       for var row =0; row < subMagic.count; ++row{

           for var col =0; col < subMagic.count; ++col{

                s[row0 + row][col0 + col] = subMagic[row][col] + iPut0

            }

        }

    }

    

    //第一步,初始化ABCD

   fillSubMagic(&solution, row0: 0, col0: 0, subMagic: subMagic, iPut0: 1)

   fillSubMagic(&solution, row0: step/2, col0: step/2, subMagic: subMagic, iPut0: step*step+1)

   fillSubMagic(&solution, row0: 0, col0: step/2, subMagic: subMagic, iPut0: step*step*2+1)

   fillSubMagic(&solution, row0: step/2, col0:0, subMagic: subMagic, iPut0: step*step*3+1)

    

    //A阵中取左侧m列与D阵对应小格对调

   let m = (subStep - 1)/2

   for var row =0; row < subStep; ++row{

       for var col =0; col < m; ++col{

           let tmp = solution[row][col]

            solution[row][col] = solution[row + subStep][col]

            solution[row + subStep][col] = tmp

        }

    }

    

    //C阵中取右侧m-1列与B阵对应小格对调

   for var row =0; row < subStep; ++row{

       for var col = step - (m -1); col < step; ++col{

           let tmp = solution[row][col]

            solution[row][col] = solution[row + subStep][col]

            solution[row + subStep][col] = tmp

        }

    }

    

    //最后在A阵中间行取中心格与左侧一格与D阵对应小格对调。

   let subStep_M = subStep/2

   let tmp = solution[subStep_M][subStep_M]

    solution[subStep_M][subStep_M] = solution[subStep_M + subStep][subStep_M]

    solution[subStep_M + subStep][subStep_M] = tmp

    

   let tmp1 = solution[subStep_M][subStep_M - 1]

    solution[subStep_M][subStep_M -1] = solution[subStep_M + subStep][subStep_M -1]

    solution[subStep_M + subStep][subStep_M -1] = tmp1

    

   return solution

}



//测试过程

func testDOStrachey(){

   func testAStep(#subMagic:[[Int]]){

       let s = DOStrachey(subMagic: subMagic)

       if let s1 = s{

           printMagic(s1)

           let k = isMagic(s1)

           if let k1 = k{

               println("这个不是幻方 k=\(k1)")

            }

            

        }else{

            println("s is not a magic square subMagic =\(subMagic)")

        }

    }

    

   testAStep(subMagic: JJMerzirac(step: 3)!)

   testAStep(subMagic: JJMerzirac(step: 5)!)

   testAStep(subMagic: JJLouberel(step: 5)!)

   testAStep(subMagic: JJHorse1(step: 5)!)

   testAStep(subMagic: JJMerzirac(step: 7)!)

   testAStep(subMagic: JJLouberel(step: 7)!)

   testAStep(subMagic: JJHorse1(step: 7)!)

}

//testDOStrachey()//打开即可打印

/*

[117, 2, 7, 81, 74, 79]

[4, 114, 8, 76, 78, 80]

[113, 10, 3, 77, 82, 75]

[9, 110, 115, 45, 38, 43]

[112, 6, 116, 40, 42, 44]

[5, 118, 111, 41, 46, 39]

经检查,行的和都是相等的

经检查,列的和都是相等的

经检查,左对角线的和都是相等的

经检查,右对角线的和都是相等的

[318, 325, 2, 9, 16, 218, 225, 202, 209, 116]

[324, 306, 8, 15, 17, 224, 206, 208, 215, 117]

[305, 7, 314, 21, 23, 205, 207, 214, 221, 123]

[311, 313, 20, 22, 4, 211, 213, 220, 222, 104]

[312, 319, 26, 3, 10, 212, 219, 226, 203, 110]

[18, 25, 302, 309, 316, 118, 125, 102, 109, 216]

[24, 6, 308, 315, 317, 124, 106, 108, 115, 217]

[5, 307, 14, 321, 323, 105, 107, 114, 121, 223]

[11, 13, 320, 322, 304, 111, 113, 120, 122, 204]

[12, 19, 326, 303, 310, 112, 119, 126, 103, 210]

经检查,行的和都是相等的

经检查,列的和都是相等的

经检查,左对角线的和都是相等的

经检查,右对角线的和都是相等的

[324, 307, 20, 3, 16, 224, 207, 220, 203, 116]

[311, 319, 2, 15, 23, 211, 219, 202, 215, 123]

[318, 6, 314, 22, 10, 218, 206, 214, 222, 110]

[305, 313, 26, 9, 17, 205, 213, 226, 209, 117]

[312, 325, 8, 21, 4, 212, 225, 208, 221, 104]

[24, 7, 320, 303, 316, 124, 107, 120, 103, 216]

[11, 19, 302, 315, 323, 111, 119, 102, 115, 223]

[18, 306, 14, 322, 310, 118, 106, 114, 122, 210]

[5, 13, 326, 309, 317, 105, 113, 126, 109, 217]

[12, 25, 308, 321, 304, 112, 125, 108, 121, 204]

经检查,行的和都是相等的

经检查,列的和都是相等的

经检查,左对角线的和都是相等的

经检查,右对角线的和都是相等的

[324, 313, 2, 21, 10, 224, 213, 202, 221, 110]

[305, 319, 8, 22, 16, 205, 219, 208, 222, 116]

[311, 25, 314, 3, 17, 211, 225, 214, 203, 117]

[312, 306, 20, 9, 23, 212, 206, 220, 209, 123]

[318, 307, 26, 15, 4, 218, 207, 226, 215, 104]

[24, 13, 302, 321, 310, 124, 113, 102, 121, 210]

[5, 19, 308, 322, 316, 105, 119, 108, 122, 216]

[11, 325, 14, 303, 317, 111, 125, 114, 103, 217]

[12, 6, 320, 309, 323, 112, 106, 120, 109, 223]

[18, 7, 326, 315, 304, 118, 107, 126, 115, 204]

经检查,行的和都是相等的

经检查,列的和都是相等的

经检查,左对角线的和都是相等的

经检查,右对角线的和都是相等的

[619, 628, 637, 2, 11, 20, 29, 423, 432, 441, 394, 403, 216, 225]

[627, 636, 596, 10, 19, 28, 30, 431, 440, 400, 402, 411, 224, 226]

[635, 595, 597, 18, 27, 36, 38, 439, 399, 401, 410, 419, 232, 234]

[594, 603, 17, 614, 35, 37, 46, 398, 407, 409, 418, 427, 233, 242]

[602, 604, 613, 34, 43, 45, 5, 406, 408, 417, 426, 435, 241, 201]

[610, 612, 621, 42, 44, 4, 13, 414, 416, 425, 434, 436, 200, 209]

[611, 620, 629, 50, 3, 12, 21, 415, 424, 433, 442, 395, 208, 217]

[31, 40, 49, 590, 599, 608, 617, 227, 236, 245, 198, 207, 412, 421]

[39, 48, 8, 598, 607, 616, 618, 235, 244, 204, 206, 215, 420, 422]

[47, 7, 9, 606, 615, 624, 626, 243, 203, 205, 214, 223, 428, 430]

[6, 15, 605, 26, 623, 625, 634, 202, 211, 213, 222, 231, 429, 438]

[14, 16, 25, 622, 631, 633, 593, 210, 212, 221, 230, 239, 437, 397]

[22, 24, 33, 630, 632, 592, 601, 218, 220, 229, 238, 240, 396, 405]

[23, 32, 41, 638, 591, 600, 609, 219, 228, 237, 246, 199, 404, 413]

经检查,行的和都是相等的

经检查,列的和都是相等的

经检查,左对角线的和都是相等的

经检查,右对角线的和都是相等的

[635, 604, 629, 10, 35, 4, 29, 439, 408, 433, 402, 427, 200, 225]

[610, 628, 597, 34, 3, 28, 46, 414, 432, 401, 426, 395, 224, 242]

[627, 603, 621, 2, 27, 45, 21, 431, 407, 425, 394, 419, 241, 217]

[602, 620, 8, 614, 44, 20, 38, 406, 424, 400, 418, 436, 216, 234]

[619, 595, 613, 50, 19, 37, 13, 423, 399, 417, 442, 411, 233, 209]

[594, 612, 637, 18, 43, 12, 30, 398, 416, 441, 410, 435, 208, 226]

[611, 636, 605, 42, 11, 36, 5, 415, 440, 409, 434, 403, 232, 201]

[47, 16, 41, 598, 623, 592, 617, 243, 212, 237, 206, 231, 396, 421]

[22, 40, 9, 622, 591, 616, 634, 218, 236, 205, 230, 199, 420, 438]

[39, 15, 33, 590, 615, 633, 609, 235, 211, 229, 198, 223, 437, 413]

[14, 32, 596, 26, 632, 608, 626, 210, 228, 204, 222, 240, 412, 430]

[31, 7, 25, 638, 607, 625, 601, 227, 203, 221, 246, 215, 429, 405]

[6, 24, 49, 606, 631, 600, 618, 202, 220, 245, 214, 239, 404, 422]

[23, 48, 17, 630, 599, 624, 593, 219, 244, 213, 238, 207, 428, 397]

经检查,行的和都是相等的

经检查,列的和都是相等的

经检查,左对角线的和都是相等的

经检查,右对角线的和都是相等的

[635, 620, 605, 2, 43, 28, 13, 439, 424, 409, 394, 435, 224, 209]

[594, 628, 613, 10, 44, 36, 21, 398, 432, 417, 402, 436, 232, 217]

[602, 636, 621, 18, 3, 37, 29, 406, 440, 425, 410, 395, 233, 225]

[610, 595, 41, 614, 11, 45, 30, 414, 399, 433, 418, 403, 241, 226]

[611, 603, 637, 34, 19, 4, 38, 415, 407, 441, 426, 411, 200, 234]

[619, 604, 596, 42, 27, 12, 46, 423, 408, 400, 434, 419, 208, 242]

[627, 612, 597, 50, 35, 20, 5, 431, 416, 401, 442, 427, 216, 201]

[47, 32, 17, 590, 631, 616, 601, 243, 228, 213, 198, 239, 420, 405]

[6, 40, 25, 598, 632, 624, 609, 202, 236, 221, 206, 240, 428, 413]

[14, 48, 33, 606, 591, 625, 617, 210, 244, 229, 214, 199, 429, 421]

[22, 7, 629, 26, 599, 633, 618, 218, 203, 237, 222, 207, 437, 422]

[23, 15, 49, 622, 607, 592, 626, 219, 211, 245, 230, 215, 396, 430]

[31, 16, 8, 630, 615, 600, 634, 227, 212, 204, 238, 223, 404, 438]

[39, 24, 9, 638, 623, 608, 593, 235, 220, 205, 246, 231, 412, 397]

经检查,行的和都是相等的

经检查,列的和都是相等的

经检查,左对角线的和都是相等的

经检查,右对角线的和都是相等的

*/



0 0
原创粉丝点击