使用DuckDB SQL求三阶六角幻方

六角幻方
https://zhuanlan.zhihu.com/p/544255474
原图如下:
在这里插入图片描述

条件:最外圈是3个在同一边的数之和相等,还要配上对角线的5个数相等,间隔1条边的两边中点连线上的4个数和相等。
根据横排5排的和都相等,可知这个和=38((1+19)*19/2/5)

with recursive n as(select i from range(1, 20)t(i)) --1 到 19 
, n3 as (select (1<<a)+(1<<b)m, * from(select n.i a,n1.i b, 38-n.i-n1.i c from n, n n1) where a<>b and a<>c and b<>c and c between 1 and 19 ) -- 找出和为38的三元组
,r as(select 1 lv,[a,b] s,n3.* from n3 -- 将和为38的三元组按首尾数字连成串
union all
select lv+1, s+ [n3.a,n3.b],n3.m+r.m,n3.a,n3.b,n3.c from r,n3 where r.c=n3.a and r.m&n3.m=0 and lv<6)
,t as(select * from r where lv=6 and c=s[1]) --串成闭环
,a as(select m, s,[38-s[12]-s[4],38-s[2]-s[6],38-s[4]-s[8],38-s[10]-s[6],38-s[12]-s[8],38-s[10]-s[2]]t from t) --算出每种排列中圈相邻两数和
,b as(select 1 lv,a.m+(1<<n.i)+(1<<n1.i) m,s+[n.i,n1.i] s,t,n1.i i from a,n,n n1 where a.m &(1<<n.i)=0 and a.m &(1<<n1.i)=0 and n.i+n1.i=t[1] and n.i<>n1.i -- 从剩余的数字中试拼
union all
select lv+1,m+(1<<n1.i),s+[n1.i],t,n1.i from b,n n1  where m &(1<<n1.i)=0 and n1.i+b.i=t[lv+1] and lv<5
)
select * from b where lv=5 --1 因为已知唯一解,这些都是对称、旋转后的结果
;
┌───────┬─────────┬──────────────────────────────────────────────────────────────────┬──────────────────────┬───────┐
│  lv   │    m    │                                s                                 │          t           │   i   │
│ int32 │  int64  │                             int64[]                              │       int64[]        │ int64 │
├───────┼─────────┼──────────────────────────────────────────────────────────────────┼──────────────────────┼───────┤
│     51048542[3, 19, 16, 12, 10, 13, 15, 14, 9, 11, 18, 17, 7, 2, 4, 8, 6, 1][9, 6, 12, 14, 7, 8]1 │
│     51048542[9, 14, 15, 13, 10, 12, 16, 19, 3, 17, 18, 11, 6, 8, 4, 2, 7, 1][14, 12, 6, 9, 8, 7]1 │
│     51048542[3, 17, 18, 11, 9, 14, 15, 13, 10, 12, 16, 19, 7, 1, 6, 8, 4, 2][8, 7, 14, 12, 6, 9]2 │
│     51048542[10, 13, 15, 14, 9, 11, 18, 17, 3, 19, 16, 12, 4, 8, 6, 1, 7, 2][12, 14, 7, 8, 9, 6]2 │
│     51048542[15, 14, 9, 11, 18, 17, 3, 19, 16, 12, 10, 13, 8, 6, 1, 7, 2, 4][14, 7, 8, 9, 6, 12]4 │
│     51048542[16, 19, 3, 17, 18, 11, 9, 14, 15, 13, 10, 12, 2, 7, 1, 6, 8, 4][9, 8, 7, 14, 12, 6]4 │
│     51048542[15, 13, 10, 12, 16, 19, 3, 17, 18, 11, 9, 14, 8, 4, 2, 7, 1, 6][12, 6, 9, 8, 7, 14]6 │
│     51048542[18, 17, 3, 19, 16, 12, 10, 13, 15, 14, 9, 11, 1, 7, 2, 4, 8, 6][8, 9, 6, 12, 14, 7]6 │
│     51048542[16, 12, 10, 13, 15, 14, 9, 11, 18, 17, 3, 19, 2, 4, 8, 6, 1, 7][6, 12, 14, 7, 8, 9]7 │
│     51048542[18, 11, 9, 14, 15, 13, 10, 12, 16, 19, 3, 17, 1, 6, 8, 4, 2, 7][7, 14, 12, 6, 9, 8]7 │
│     51048542[9, 11, 18, 17, 3, 19, 16, 12, 10, 13, 15, 14, 6, 1, 7, 2, 4, 8][7, 8, 9, 6, 12, 14]8 │
│     51048542[10, 12, 16, 19, 3, 17, 18, 11, 9, 14, 15, 13, 4, 2, 7, 1, 6, 8][6, 9, 8, 7, 14, 12]8 │
├───────┴─────────┴──────────────────────────────────────────────────────────────────┴──────────────────────┴───────┤
│ 12 rows                                                                                                 5 columns │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 0.242 user 0.265625 sys 0.125000
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值