利用DeepSeek改写SQLite版本的二进制位数独求解SQL

把二进制位方法用于SQLite版本有一个问题需要解决,就是用字符串代替数组存储二进制状态,我在DuckDB版本基础上,把list函数改为GROUP_CONCAT,然后将语句和如下提示发给DeepSeek、

原SQLite版本计算初始化二进制状态有错,改成如下思路,并且不用逗号分隔,用定长3位十进制字符,更新时只需要拼接,不用replace。

他给出了如下的代码

sql 复制代码
WITH RECURSIVE
  input(sud) AS (
    VALUES('9......4..5..2........1......69..1........5.24..7......1....3.....6...9....4.....')
    --VALUES('.....1..7....6..2.8..9..3...954....3..3...4..4......8......7..6.1..2....5..3..9..')
  ),
  digits(z, lp, bit) AS (
    VALUES('1', 1, 1)
    UNION ALL SELECT 
    CAST(lp+1 AS TEXT), lp+1, bit * 2 FROM digits WHERE lp<9
  ),
  -- 初始化行列宫的二进制状态(基于已有数字)
  init_state AS (
    SELECT 
      sud,
      (
        select GROUP_CONCAT(s ,'') from(select substr(1000+sum(bit),2)s,rn from (select bit,value/9 rn from digits, generate_series(0,80) where substr(sud,value+1,1)=z union all select 0,value from generate_series(0,8)) group by rn order by rn)
      ) as rows,
      (
        select GROUP_CONCAT(s ,'') from(select substr(1000+sum(bit),2)s,rn from (select bit,value%9 rn from digits, generate_series(0,80) where substr(sud,value+1,1)=z union all select 0,value from generate_series(0,8)) group by rn order by rn)
      ) as cols,
      (
        select GROUP_CONCAT(s ,'') from(select substr(1000+sum(bit),2)s,rn from (select bit,(value/27*3 + value%9/3) rn from digits, generate_series(0,80) where substr(sud,value+1,1)=z union all select 0,value from generate_series(0,8)) group by rn order by rn)
      ) as boxes
    FROM input
  ),
  -- 递归求解
  x(s, ind, rows, cols, boxes) AS (
    SELECT 
      sud, 
      instr(sud, '.'),
      rows,
      cols,
      boxes
    FROM init_state
    UNION ALL
    SELECT
      substr(s, 1, ind-1) || z || substr(s, ind+1),
      instr( substr(s, 1, ind-1) || z || substr(s, ind+1), '.' ),
      -- 更新行的二进制状态
      substr(rows, 1, ((ind-1)/9)*3) || 
      substr(1000 + (CAST(substr(rows, ((ind-1)/9)*3+1, 3) AS INTEGER) | z.bit), 2) ||
      substr(rows, ((ind-1)/9)*3+4),
      -- 更新列的二进制状态
      substr(cols, 1, ((ind-1)%9)*3) ||
      substr(1000 + (CAST(substr(cols, ((ind-1)%9)*3+1, 3) AS INTEGER) | z.bit), 2) ||
      substr(cols, ((ind-1)%9)*3+4),
      -- 更新宫的二进制状态
      substr(boxes, 1, (((ind-1)/27)*3 + ((ind-1)%9)/3)*3) ||
      substr(1000 + (CAST(substr(boxes, (((ind-1)/27)*3 + ((ind-1)%9)/3)*3+1, 3) AS INTEGER) | z.bit), 2) ||
      substr(boxes, (((ind-1)/27)*3 + ((ind-1)%9)/3)*3+4)
    FROM x, digits AS z
    WHERE ind>0
      AND z.lp BETWEEN 1 AND 9
      -- 使用位运算检查是否可以放置数字
      AND (CAST(substr(rows, ((ind-1)/9)*3+1, 3) AS INTEGER) & z.bit) = 0
      AND (CAST(substr(cols, ((ind-1)%9)*3+1, 3) AS INTEGER) & z.bit) = 0
      AND (CAST(substr(boxes, (((ind-1)/27)*3 + ((ind-1)%9)/3)*3+1, 3) AS INTEGER) & z.bit) = 0
  )
SELECT s FROM x WHERE ind=0;

它计算原有的例子没问题。但是我把只有17个已知数的最小数独给它,却算不出来,经过调试发现,当某行全为空时,它不返回sum值,导致二进制状态缺行,再次让DeepSeek修改,他给出的解决方法是COALESCE或左连接,但实际上不能用,还是手工把它改成union all 一个行号0值序列,再做分组,此思路已改在上述代码,现在就能处理最小数独了。

把上述代码保存为 dssql2.txt,将它与原始SQLite示例比较,结果如下

sql 复制代码
-- 原有例子
sqlite> .read dssql2.txt

┌──────────────────────────────────────────────────────────────┐
│                              s                               │
├──────────────────────────────────────────────────────────────┤
│ 346251897759863124821974365195486273683712459472539681238197 │
│ 546914625738567348912                                        │
└──────────────────────────────────────────────────────────────┘
Run Time: real 3.376290 user 3.344000 sys 0.032000
sqlite> .read sqlsudoku.txt
┌──────────────────────────────────────────────────────────────┐
│                              s                               │
├──────────────────────────────────────────────────────────────┤
│ 346251897759863124821974365195486273683712459472539681238197 │
│ 546914625738567348912                                        │
└──────────────────────────────────────────────────────────────┘
Run Time: real 10.713583 user 10.660000 sys 0.028000
-- 17个已知数的最小数独
sqlite> .read sqlsudoku.txt
┌──────────────────────────────────────────────────────────────┐
│                              s                               │
├──────────────────────────────────────────────────────────────┤
│ 932567841157824963648319725576982134893146572421753689714298 │
│ 356285631497369475218                                        │
└──────────────────────────────────────────────────────────────┘
Run Time: real 72.085067 user 71.812000 sys 0.264000

sqlite> .read dssql2.txt
┌──────────────────────────────────────────────────────────────┐
│                              s                               │
├──────────────────────────────────────────────────────────────┤
│ 932567841157824963648319725576982134893146572421753689714298 │
│ 356285631497369475218                                        │
└──────────────────────────────────────────────────────────────┘
Run Time: real 21.870196 user 21.292000 sys 0.388000

可见,尽管需要把数字存在字符串,二进制位版本还是比原始版本快了3倍。

相关推荐
q***614118 小时前
Spring中Aware的用法以及实现
java·数据库·spring
红树林0718 小时前
渗透测试之sql注入--报错注入
数据库·sql·安全·web安全
菜鸟小九19 小时前
mysql(锁)
数据库·mysql·oracle
c***421019 小时前
【Sql Server】随机查询一条表记录,并重重温回顾下自定义函数的封装和使用
数据库·性能优化
Appreciate(欣赏)19 小时前
JAVA使用poi类读取xlxs文件内容拼接成添加数据SQL
java·开发语言·sql
johnny23319 小时前
AI工作流编排平台
人工智能
q***448120 小时前
PostgreSQL的备份方式
数据库·postgresql
v***598320 小时前
【SQL Server】超详细SQLServer日期转换、字符串、数学、聚合等常用函数大全(最新版)
数据库·sqlserver
q***235720 小时前
python的sql解析库-sqlparse
数据库·python·sql
百***354820 小时前
DeepSeek在情感分析中的细粒度识别
人工智能