Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 用关系数据库解决密码算法难题_Sql_Relational Database_Cryptarithmetic Puzzle - Fatal编程技术网

Sql 用关系数据库解决密码算法难题

Sql 用关系数据库解决密码算法难题,sql,relational-database,cryptarithmetic-puzzle,Sql,Relational Database,Cryptarithmetic Puzzle,假设您获得了密码算术难题: 发送+更多=金钱 目标是用数字(0-9)代替字母,这样加法就行了 我知道如何从数学上解决这个问题,但我不知道如何用关系数据库解决这个问题 如何设计模式来解决此问题? 试图解决此问题的SQL查询的外观如何? 编辑: 有一些限制: 对于给定的字母,应始终使用相同的数字。例如,如果 你猜字母E是“5”,那么E应该在它的所有位置都得到值“5” 发生 不同的字母应该有不同的数字,例如,您不能同时为这两个字母指定“4” E和M 所有数字(单词)都不能有任何前导零 作者提出了两个截

假设您获得了密码算术难题:

发送+更多=金钱

目标是用数字(0-9)代替字母,这样加法就行了

我知道如何从数学上解决这个问题,但我不知道如何用关系数据库解决这个问题

如何设计模式来解决此问题?

试图解决此问题的SQL查询的外观如何?

编辑: 有一些限制:

  • 对于给定的字母,应始终使用相同的数字。例如,如果 你猜字母E是“5”,那么E应该在它的所有位置都得到值“5” 发生
  • 不同的字母应该有不同的数字,例如,您不能同时为这两个字母指定“4” E和M
  • 所有数字(单词)都不能有任何前导零

  • 作者提出了两个截然不同的问题

    这回答了所提出的问题,OVER+FLOW=STACK,其中每个字符不一定有唯一的数字,并且可能涉及10个以上的字符

    • 有一个规定,每个字符接收一个唯一的数字,但这对于OVER+FLOW+STACK是不可能的,因为有太多的字母
    Digits
    表包含一列,而earch记录包含一个介于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)
    
    根据我对这个问题的理解,有多种解决方案。以下是此代码找到的前5个:

    我删除了0,因为你可以用0替换每个字母,并得到一个便宜的答案(基于你最初的问题修订)

    这是唯一的表
    数字


    这回答了用户提出的另一个问题。

    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
    
    SEND+MORE=货币,其中每个字符都有一个唯一的数字,并且没有以零开头的单词

    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
    
    选择
    第一名
    S.num作为S,
    E.num作为E,
    N.num作为N,
    D.num作为D,
    M.num作为M,
    O.num作为O,
    R.num作为R,
    Y.num作为Y,
    (S.num*1000+E.num*100+N.num*10+D.num)作为[SEND],
    (M.num*1000+O.num*100+R.num*10+E.num)以及更多,
    (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)作为[货币]
    从…起
    数字为S
    将数字连接为E.num S.num上的E
    将数字连接为N.num S.num和N.num E.num上的N
    在D.num S.num和D.num E.num和D.num N.num上将数字连接为D
    将数字连接为M.num S.num和M.num E.num和M.num N.num和M.num D.num上的M
    将数字连接为O.num S.num和O.num E.num和O.num N.num和O.num D.num和O.num M.num上的O
    将数字合并为R.num S.num和R.num E.num和R.num N.num和R.num D.num和R.num M.num和R.num O.num上的R
    将数字连接为Y.num S.num和Y.num E.num和Y.num N.num和Y.num D.num和Y.num M.num和Y.num O.num和Y.num R.num上的Y
    哪里
    (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)
    以及S.num 0和M.num 0
    
    我曾考虑在WHERE子句中强制使用唯一数字,但我相信这最终会在检查WHERE子句之前处理太多的排列

    由于我们只处理最多10位数字,我认为最好是构建long-ON子句,而不是考虑速度问题

    这里是FROM+WHERE子句,没有疯狂的ON子句。这在我的服务器上运行要慢得多。

    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
    
    来自
    数字为S
    将数字交叉连接为E
    交叉连接数字为N
    将数字交叉连接为D
    交叉连接数字为M
    交叉连接数字为O
    交叉连接数字为R
    将数字交叉连接为Y
    哪里
    (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)
    以及S.num 0和M.num 0
    和(从中选择最大值(B.计数)
    (选择COUNT(*)作为从中的计数
    (选择S.num,'S'作为字母——包含字母以确保联合不会合并等效行
    联合选择E.num,“E”
    联合选择N.num,“N”
    联合选择D.num,“D”
    联合选择M.num,“M”
    联合选择O.num,“O”
    联合选择R.num,“R”
    联合选择Y.num,“Y”)作为
    按A.num分组
    )作为B
    ) = 1
    
    单词长度是否有最大限制?一次只能解决一个难题,因此可以专门为该尝试创建/修改表格。拼图的格式都是长度(4)+长度(4)=长度(5)。你的第一次编辑是不可能的,有10多个不同的字母。每个字母不能有自己的数字。字母不能相乘。它们被连接成1个长整数。O=1,V=2,E=3,R=4==>1234对于我提供的方程来说,这个规定可能是不可能的,因为我只是为了StackOverflow改变了实际问题。实际问题是发送+更多=金钱