首页 > 代码库 > 采用F#推导洛书

采用F#推导洛书

洛书:古称龟书,传说有神龟出于洛水,其甲壳上有此图象,结构是戴九履一,左三右七,二四为肩,六八为足,以五居中,五方白圈皆阳数,四隅黑点为阴数。

 

设计算法寻找此图

  • 1-9个数不能重复
  • 横向数字之和为15
  • 纵向数字之和为15
  • 斜向数字之和为15

代码如下

// 运用 F# 推导洛书// See more infomation on http://www.1wuyou.com for more help.let example = [|[|0;0;0|];                [|0;0;0|];                [|0;0;0|];|]let size2 = 9;let size = 3let rec invalidNine (m:int array array) (index:int) shu =    match index with        | 9 -> false        | index when m.[index/3].[index%3] = shu -> true        | _->             invalidNine m (index+1) shulet rec invalidH (m:int array array) s x y (shu:int) (num:int) (sum:int) (dir:int)=     if num = 3 then        if sum = 15 then Some(false)         else Some(true)    else       match s,x,y with        | Some(true),x,y ->Some(true)        | None,x,y -> None        | s,x,y when m.[x].[y] = 0 && num>0 -> None        | _ ->             let addnum = if num =0 then shu else m.[x].[y]            match dir with            | 1 -> invalidH m s ((x+1)%3) y shu (num+1) (sum+addnum) dir                //水平            | 2 -> invalidH m s x ((y+1)%3) shu (num+1) (sum+addnum) dir                //垂直            | 3 -> if (x+y)%2=1 then None else                        invalidH m s ((x+1)%3)  ((y+1)%3) shu (num+1) (sum+addnum) dir  //右下            | 4 -> if (x+y)%2=1 then None else                        invalidH m s ((x+1)%3)  ((y-1+3)%3) shu (num+1) (sum+addnum) dir //右上    let Tinvalid m x y shu =     invalidNine m 0 shu     ||invalidH m (Some(false)) x y shu 0 0 1 = Some(true)    ||invalidH m (Some(false)) x y shu 0 0 2 = Some(true)    ||invalidH m (Some(false)) x y shu 0 0 3 = Some(true)    ||invalidH m (Some(false)) x y shu 0 0 4 = Some(true)let rec search m x y f accu =    match x ,y with        | x,y when x = 3 -> search m 0 (y+1) f accu        | 0,y when y = 3 ->             printfn " 找到一个."            //example |>Array.iter (fun t->printfn "%A" t)            f accu        | x,y ->            let aux accu n =                 if Tinvalid m  x y n  then accu else                    (m.[x].[y] <- n;                    let accu =  search m (x+1) y f accu in                    m.[x].[y] <- 0;                    accu) in            List.fold aux accu [1..9]                    exception Exit[<EntryPoint>]let main argv =     try      printfn "开始发现洛书 "       search example (0+0) 0 (fun s -> if example.[0].[0]=4 && example.[0].[2]=2 then raise Exit) ()     with         |Exit -> printfn "易无忧找到真正洛书 "          example |>Array.iter (fun t->printfn "%A" t)        0 
View Code

 

输出结果

开始发现洛书 找到一个. 找到一个. 找到一个.易无忧找到真正洛书[|4; 9; 2|][|3; 5; 7|][|8; 1; 6|]请按任意键继续. . .

 

结果分析:

   事实上我们共得到了8幅洛书 ,这几幅洛书就像是一张透明的正方扑克摆出了八种形态, 但真正的洛书只有一个,我们直接采用最终符合的判定进行了输出,

   为什么唯一的洛书只有一份呢?这个确实一直值得思考的问题,

4巽宫
9离宫
2坤宫
3震宫
5中宫
7兑宫
8艮宫
1坎宫
6乾宫

 此表与后天八卦卦序相对甚密 ,其中是有一定的联系的,其中的时序与方位是与我中华大地的位置南热北冷西高东低,太阳的东升西落四季更替等时空顺序是一致的。