幻方解法之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,依次向右上方填入2、3、4…,如果右上方已有数字,则向上移两格继续填写。如下图用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斜步相应的跳步可以为2X,2Y。【记住,跳步是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]
*/
- 幻方解法之Louberel法生成奇阶幻方
- 幻方解法之Merzirac法生成奇阶幻方
- 幻方解法之horse法生成奇阶幻方
- 幻方解法之错位补角法生成奇阶幻方
- 幻方解法之Spring法生成双偶幻方
- 幻方解法之Strachey法生成单偶幻方
- 幻方解法之Strachey法生成双偶幻方
- 幻方解法之总结篇
- 幻方解法之swift语言程序实现开篇
- (ZT)幻方常规解法汇总
- c++幻方的解法与判断
- 幻方的生成
- 幻方的生成
- 幻立方解法之7阶幻立方的生成方法
- 幻立方解法之开篇
- poj2253 frog之最小生成树prim解法
- POJ2349Arctic Network之最小生成树kruskal解法
- AutoHotkey用楼梯法生成奇数幻方
- SSH项目中,hql语句和sql语句的区别?
- Javad的Validator框架概述
- php中break,continue,exit的使用与区别
- eclipse 打点.不出提示(alt+/不出提示 )
- (转)MapReuce 编程总结-多MapReduce执行
- 幻方解法之Louberel法生成奇阶幻方
- Unix 网络编程(一)- 你的第一个socket程序“Daytimetcp”
- android 数据存储操作3:文件读写
- 内网渗透专家-----ngrok
- GHOST: glibc vulnerability (CVE-2015-0235)#GHOST(幽灵)漏洞修复
- Botton控件
- 串口通信中ReadFile和WriteFile的超时详解!
- GetDlgItem
- openCV,C++接口,cv::Mat矩阵数据元素读取