幻方解法之Louberel法生成奇阶幻方

来源:互联网 发布:java编程思想4 源代码 编辑:程序博客网 时间:2024/04/30 06:01

/*

程序思想参考百度百科上"幻方法则" 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

*/


/*

在居中的方格向上一格内放1,依次向右上方填入234…,如果右上方已有数字,则向上移两格继续填写。如下图用Louberel法生成的5阶幻方:

23 6 19 2 15

10 18 1 14 22

17 5 13 21 9

4 12 25 8 16

11 24 7 20 3

*/

func JJLouberel(#step:Int) -> ([[Int]])?{

   if (step < 3) {returnnil}

   if (step % 2 ==0) {return nil}

    

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

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

    

    //要赋值的位置,初始化为居中的方格向上一格

   var row = step/2 -1  //中间行的上一行

   var col = step/2 //中间列

   var iPut = 1 //放这个数

    //居中的方格向上一格放1

    solution[row][col] = iPut++

   var time = step * step - 1

   do{

        //下一个赋值的位置

       var nextcol = col + 1

       var nextrow = row - 1

        

        nextcol =correction(nextcol,step)

        nextrow =correction(nextrow,step)

        

       if solution[nextrow][nextcol] != 0{

            nextrow = row -2

            nextrow =correction(nextrow,step)

            nextcol = col

           if solution[nextrow][col] != 0{

               return solution

            }

        }

        

        row = nextrow

        col = nextcol

        solution[row][col] = iPut++

        

    }while(time-- >0)

    

    return nil

}


//测试过程

func testJJLouberel(){

   func testAStep(step: Int){

       let s = JJLouberel(step: step)

       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 step =\(step)")

        }

    }

    

    testAStep(3)

    testAStep(5)

    testAStep(7)

    testAStep(9)

}

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

/*

[8, 1, 6]

[3, 5, 7]

[4, 9, 2]

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

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

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

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

[23, 6, 19, 2, 15]

[10, 18, 1, 14, 22]

[17, 5, 13, 21, 9]

[4, 12, 25, 8, 16]

[11, 24, 7, 20, 3]

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

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

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

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

[46, 15, 40, 9, 34, 3, 28]

[21, 39, 8, 33, 2, 27, 45]

[38, 14, 32, 1, 26, 44, 20]

[13, 31, 7, 25, 43, 19, 37]

[30, 6, 24, 49, 18, 36, 12]

[5, 23, 48, 17, 42, 11, 29]

[22, 47, 16, 41, 10, 35, 4]

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

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

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

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

[77, 28, 69, 20, 61, 12, 53, 4, 45]

[36, 68, 19, 60, 11, 52, 3, 44, 76]

[67, 27, 59, 10, 51, 2, 43, 75, 35]

[26, 58, 18, 50, 1, 42, 74, 34, 66]

[57, 17, 49, 9, 41, 73, 33, 65, 25]

[16, 48, 8, 40, 81, 32, 64, 24, 56]

[47, 7, 39, 80, 31, 72, 23, 55, 15]

[6, 38, 79, 30, 71, 22, 63, 14, 46]

[37, 78, 29, 70, 21, 62, 13, 54, 5]

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

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

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

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

*/


/*

上述loubere法可以记作X+Y斜步(数字按右上方顺序填入),2Y跳步(如果右上方已有数字或出了对角线,则向上移二格继续填写)。对于X+Y斜步相应的跳步可以为2X2Y【记住,跳步是X+Y斜步的X(或Y)相同方向即可。】

2Y跳步,则在居中的方格向上一格放1里,按上斜步,2Y跳步的方法构成幻方。

-2Y跳步,则在居中的方格向下一格放1里,按下斜步,-2Y跳步的方法构成幻方。

2X跳步,则在居中的方格向右一格放1里,按右斜步,2X跳步的方法构成幻方。

-2X跳步,则在居中的方格向左一格放1里,按左斜步,-2X跳步的方法构成幻方。

*/

/*

step表示幻方阶数

deltaX,deltaY表示X方向,Y方向步长

jumpX表示跳步时是X方向,否则y方向

经测试并不是上面说的对于X+Y斜步相应的跳步可以为-X-Y”

可我的测试结果却发现这个扩展不对

下面是我写的程序以及测试结果

若有对原文理解不对的地方,请指正

*/

func JJLoubereExtend(#step:Int, #deltaX: Int, #deltaY:Int, jumpX: Bool =false) -> ([[Int]])?{

   if (step < 3) {returnnil}

   if (step % 2 ==0) {return nil}

    

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

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

    

    //要赋值的位置,初始化为居中的方格向上一格

   var row = step/2 -1  //中间行的上一行

   var col = step/2 //中间列

   var iPut = 1 //放这个数

    //第一行居中的方格内放1

    solution[row][col] = iPut++

   var time = step * step - 1

   do{

//        println("time:\(time)")

        //下一个赋值的位置

       var nextcol = col + deltaX

       var nextrow = row - deltaY

        

        nextcol =correction(nextcol,step)

        nextrow =correction(nextrow,step)

//        println("nextrow:\(nextrow)  nextcol:\(nextcol)")

        

       if solution[nextrow][nextcol] != 0{

           if jumpX{//x轴上跳步

                

                nextcol = col +2 * deltaX

                nextcol =correction(nextcol,step)

                nextrow = row

//                println("row:\(row)  nextcol:\(nextcol)")

               if solution[row][nextcol] != 0{

                   return solution

                }

            }else{//y轴上跳步

                nextrow = row -2 * deltaY

                nextrow =correction(nextrow,step)

                nextcol = col

//                println("nextrow:\(nextrow)  col:\(col)")

               if solution[nextrow][col] != 0{

                   return solution

                }

            }

        }

        row = nextrow

        col = nextcol

//        println("row:\(row)  col:\(col)")

        solution[row][col] = iPut++

        

        

    }while(time-- >0)

    

    return nil

}



//测试过程

func testJJLoubereExtend(){

   func testAStep(#step: Int, #deltaX: Int, #deltaY: Int, jumpX: Bool = false){

       let s = JJLoubereExtend(step: step, deltaX: deltaX, deltaY: deltaY, jumpX: jumpX)

       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 step =\(step)")

        }

    }

    println("右上上跳11")

   testAStep(step: 5,deltaX:1,deltaY: 1)//右上

    println("右上上跳12")

   testAStep(step: 5,deltaX:1,deltaY: 2)//右上

    println("右上上跳13")

   testAStep(step: 5,deltaX:1,deltaY: 3)//右上

    println("右上上跳14")

   testAStep(step: 5,deltaX:1,deltaY: 4)//右上

    println("右上上跳15")

   testAStep(step: 5,deltaX:1,deltaY: 5)//右上

    println("右上上跳11")

   testAStep(step: 5,deltaX:1,deltaY: 1)//右上

    println("右上上跳21")

   testAStep(step: 5,deltaX:2,deltaY: 1)//右上

    println("右上上跳31")

   testAStep(step: 5,deltaX:3,deltaY: 1)//右上

    println("右上上跳41")

   testAStep(step: 5,deltaX:4,deltaY: 1)//右上

    println("右上上跳51")

   testAStep(step: 5,deltaX:5,deltaY: 1)//右上

    println("右上右跳")

   testAStep(step: 5,deltaX:1,deltaY: 1,jumpX:true)//右上

    println("右下下跳")

   testAStep(step: 5,deltaX:1,deltaY: -1)//右下

    println("右下右跳")

   testAStep(step: 5,deltaX:1,deltaY: -1,jumpX:true)//右下

    println("左上上跳")

   testAStep(step: 5,deltaX: -1,deltaY:1)//左上

    println("左上左跳")

   testAStep(step: 5,deltaX: -1,deltaY:1,jumpX:true)//左上

    println("左下下跳")

   testAStep(step: 5,deltaX: -1,deltaY: -1)//左下

    println("左下左跳")

   testAStep(step: 5,deltaX: -1,deltaY: -1,jumpX:true)//左下

    

}

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


/*


右上上跳11

[23, 6, 19, 2, 15]

[10, 18, 1, 14, 22]

[17, 5, 13, 21, 9]

[4, 12, 25, 8, 16]

[11, 24, 7, 20, 3]

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

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

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

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

右上上跳12

[4, 12, 25, 8, 16]

[10, 18, 1, 14, 22]

[11, 24, 7, 20, 3]

[17, 5, 13, 21, 9]

[23, 6, 19, 2, 15]

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

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

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

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

右上上跳13

[11, 24, 7, 20, 3]

[10, 18, 1, 14, 22]

[4, 12, 25, 8, 16]

[23, 6, 19, 2, 15]

[17, 5, 13, 21, 9]

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

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

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

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

右上上跳14

[17, 5, 13, 21, 9]

[10, 18, 1, 14, 22]

[23, 6, 19, 2, 15]

[11, 24, 7, 20, 3]

[4, 12, 25, 8, 16]

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

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

这个不是幻方 k=[1, 1]

右上上跳15

[0, 0, 0, 0, 0]

[4, 5, 1, 2, 3]

[0, 0, 0, 0, 0]

[0, 0, 0, 0, 0]

[0, 0, 0, 0, 0]

这个不是幻方 k=[1, 0]

右上上跳11

[23, 6, 19, 2, 15]

[10, 18, 1, 14, 22]

[17, 5, 13, 21, 9]

[4, 12, 25, 8, 16]

[11, 24, 7, 20, 3]

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

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

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

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

右上上跳21

[6, 15, 19, 23, 2]

[18, 22, 1, 10, 14]

[5, 9, 13, 17, 21]

[12, 16, 25, 4, 8]

[24, 3, 7, 11, 20]

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

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

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

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

右上上跳31

[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]

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

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

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

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

右上上跳41

[15, 2, 19, 6, 23]

[22, 14, 1, 18, 10]

[9, 21, 13, 5, 17]

[16, 8, 25, 12, 4]

[3, 20, 7, 24, 11]

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

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

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

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

右上上跳51

[0, 0, 2, 0, 0]

[0, 0, 1, 0, 0]

[0, 0, 5, 0, 0]

[0, 0, 4, 0, 0]

[0, 0, 3, 0, 0]

这个不是幻方 k=[1, 0]

右上右跳

[8, 21, 14, 2, 20]

[25, 13, 1, 19, 7]

[12, 5, 18, 6, 24]

[4, 17, 10, 23, 11]

[16, 9, 22, 15, 3]

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

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

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

这个不是幻方 k=[1, -1]

右下下跳

[17, 5, 13, 21, 9]

[10, 18, 1, 14, 22]

[23, 6, 19, 2, 15]

[11, 24, 7, 20, 3]

[4, 12, 25, 8, 16]

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

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

这个不是幻方 k=[1, 1]

右下右跳

[12, 5, 18, 6, 24]

[25, 13, 1, 19, 7]

[8, 21, 14, 2, 20]

[16, 9, 22, 15, 3]

[4, 17, 10, 23, 11]

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

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

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

这个不是幻方 k=[1, -1]

左上上跳

[15, 2, 19, 6, 23]

[22, 14, 1, 18, 10]

[9, 21, 13, 5, 17]

[16, 8, 25, 12, 4]

[3, 20, 7, 24, 11]

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

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

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

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

左上左跳

[20, 2, 14, 21, 8]

[7, 19, 1, 13, 25]

[24, 6, 18, 5, 12]

[11, 23, 10, 17, 4]

[3, 15, 22, 9, 16]

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

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

这个不是幻方 k=[1, 1]

左下下跳

[9, 21, 13, 5, 17]

[22, 14, 1, 18, 10]

[15, 2, 19, 6, 23]

[3, 20, 7, 24, 11]

[16, 8, 25, 12, 4]

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

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

这个不是幻方 k=[1, 1]

左下左跳

[24, 6, 18, 5, 12]

[7, 19, 1, 13, 25]

[20, 2, 14, 21, 8]

[3, 15, 22, 9, 16]

[11, 23, 10, 17, 4]

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

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

这个不是幻方 k=[1, 1]

*/



0 0
原创粉丝点击