wil*_*lco 5 sql relational-database cryptarithmetic-puzzle
假设您获得了密码算术拼图:
发送+更多=金钱
目标是用数字(0-9)代替字母,这样就可以解决这个问题.
我理解如何以数学方式解决问题,但我不知道如何使用关系数据库来解决这个问题.
如何设计架构来解决这个问题?
如何尝试解决此问题的SQL查询?
编辑: 有一些限制:
这回答了用户提出的另一个问题.
SEND + MORE = MONEY,其中每个字符都有一个唯一的数字,没有单词以零开头.
select
top 1
S.num as S,
E.num as E,
N.num as N,
D.num as D,
M.num as M,
O.num as O,
R.num as R,
Y.num as Y,
(S.num * 1000 + E.num * 100 + N.num * 10 + D.num) as [SEND],
(M.num * 1000 + O.num * 100 + R.num * 10 + E.num) as MORE,
(S.num * 1000 + E.num * 100 + N.num * 10 + D.num) + (M.num * 1000 + O.num * 100 + R.num * 10 + E.num) as SEND_plus_MORE,
(M.num * 10000 + O.num * 1000 + N.num * 100 + E.num * 10 + Y.num) as [MONEY]
from
Digits as S
join digits as E on E.num <> S.num
join digits as N on N.num <> S.num and N.num <> E.num
join digits as D on D.num <> S.num and D.num <> E.num and D.num <> N.num
join digits as M on M.num <> S.num and M.num <> E.num and M.num <> N.num and M.num <> D.num
join digits as O on O.num <> S.num and O.num <> E.num and O.num <> N.num and O.num <> D.num and O.num <> M.num
join digits as R on R.num <> S.num and R.num <> E.num and R.num <> N.num and R.num <> D.num and R.num <> M.num and R.num <> O.num
join digits as Y on Y.num <> S.num and Y.num <> E.num and Y.num <> N.num and Y.num <> D.num and Y.num <> M.num and Y.num <> O.num and Y.num <> R.num
where
(S.num * 1000 + E.num * 100 + N.num * 10 + D.num)
+ (M.num * 1000 + O.num * 100 + R.num * 10 + E.num)
= (M.num * 10000 + O.num * 1000 + N.num * 100 + E.num * 10 + Y.num)
and S.num <> 0 and M.num <> 0
Run Code Online (Sandbox Code Playgroud)
我在WHERE子句中想到了强制使用唯一数字的东西,但我相信在检查WHERE子句之前,这最终会处理太多的排列.
由于我们只处理多达10位数字,我认为最好建立长ON条款而不是速度问题.
这是没有疯狂的ON子句的FROM + WHERE子句.这在我的服务器上运行速度慢了很多.
from
Digits as S
cross join digits as E
cross join digits as N
cross join digits as D
cross join digits as M
cross join digits as O
cross join digits as R
cross join digits as Y
where
(S.num * 1000 + E.num * 100 + N.num * 10 + D.num)
+ (M.num * 1000 + O.num * 100 + R.num * 10 + E.num)
= (M.num * 10000 + O.num * 1000 + N.num * 100 + E.num * 10 + Y.num)
and S.num <> 0 and M.num <> 0
and (select max(B.Count) from
(select COUNT(*) as Count from
(select S.num, 's' as letter -- the letters are included to make sure the unions do not merge equivalent rows
UNION select E.num, 'e'
UNION select N.num, 'n'
UNION select D.num, 'd'
UNION select M.num, 'm'
UNION select O.num, 'o'
UNION select R.num, 'r'
UNION select Y.num, 'y') as A
group by A.num
) as B
) = 1
Run Code Online (Sandbox Code Playgroud)
作者提出了两个不同的问题。
这回答了提出的问题,OVER + FLOW = STACK,其中每个字符不一定具有唯一的数字,并且可能涉及 10 个以上的字符
在Digits表包含一列的情况下,这样的事情可能会起作用,其中每条记录包含 1 到 9(或 0 到 9,如果您愿意)之间的整数。
交叉连接非常讨厌,性能方面,但这可能是一个起点。
select
top 5
O.num as O,
V.num as V,
E.num as E,
R.num as R,
F.num as F,
L.num as L,
W.num as W,
S.num as S,
T.num as T,
A.num as A,
C.num as C,
K.num as K,
(O.num * 1000 + V.num * 100 + E.num * 10 + R.num) as [OVER],
(F.num * 1000 + L.num * 100 + O.num * 10 + W.num) as FLOW,
(O.num * 1000 + V.num * 100 + E.num * 10 + R.num) + (F.num * 1000 + L.num * 100 + O.num * 10 + W.num) as OVER_plus_FLOW,
(S.num * 10000 + T.num * 1000 + A.num * 100 + C.num * 10 + K.num) as STACK
from
Digits as O
cross join digits as V
cross join digits as E
cross join digits as R
cross join digits as F
cross join digits as L
cross join digits as W
cross join digits as S
cross join digits as T
cross join digits as A
cross join digits as C
cross join digits as K
where
(O.num * 1000 + V.num * 100 + E.num * 10 + R.num)
+ (F.num * 1000 + L.num * 100 + O.num * 10 + W.num)
= (S.num * 10000 + T.num * 1000 + A.num * 100 + C.num * 10 + K.num)
Run Code Online (Sandbox Code Playgroud)
根据我对问题的理解,有多种解决方案。这是此代码找到的前 5 个:

我删除了 0,因为您可以用零替换每个字母并获得便宜的答案(基于您最初的问题修订)。
这是唯一的桌子 Digits

| 归档时间: |
|
| 查看次数: |
781 次 |
| 最近记录: |