DeepSeek辅助编写的利用唯一可选数求解数独SQL

前面用python实现了逻辑,

把迭代填充唯一可选数逻辑改写成一句postgresql格式SQL,输入表sudoku包括id,puzzle,输出包括id,puzzle,result,unkown列,如果已解决,unkown列为0,否则为剩余0的个数

sql 复制代码
WITH RECURSIVE sudoku_solver AS (
    SELECT 
        id,
        puzzle,
        puzzle as current_state,
        0 as iteration
    FROM sudoku
    
    UNION ALL
    
    SELECT 
        s.id,
        s.puzzle,
        new_state,
        s.iteration + 1
    FROM sudoku_solver s
    CROSS JOIN LATERAL (
        -- 计算当前状态的候选数和唯一候选数
        WITH current_chars AS (
            SELECT generate_series(1, 81) as pos, 
                   substr(s.current_state, generate_series(1, 81), 1) as ch
        ),
        candidates AS (
            SELECT 
                cc.pos,
                array_agg(n.n ORDER BY n.n) as cand_array
            FROM current_chars cc
            CROSS JOIN generate_series(1, 9) n(n)
            WHERE cc.ch = '0'
            AND NOT EXISTS (
                SELECT 1
                FROM current_chars cc2
                WHERE ((cc.pos-1)/9) = ((cc2.pos-1)/9)
                  AND cc2.ch = n.n::text
                UNION ALL
                SELECT 1
                FROM current_chars cc2
                WHERE ((cc.pos-1)%9) = ((cc2.pos-1)%9)
                  AND cc2.ch = n.n::text
                UNION ALL
                SELECT 1
                FROM current_chars cc2
                WHERE 
                    ((cc.pos-1)/27) = ((cc2.pos-1)/27)
                    AND (((cc.pos-1)%9)/3) = (((cc2.pos-1)%9)/3)
                    AND cc2.ch = n.n::text
            )
            GROUP BY cc.pos
        ),
        unique_candidates AS (
            SELECT pos, cand_array[1] as val
            FROM candidates
            WHERE array_length(cand_array, 1) = 1
        )
        SELECT 
            string_agg(
                CASE 
                    WHEN uc.pos IS NOT NULL THEN uc.val::text
                    ELSE substr(s.current_state, p.pos, 1)
                END, 
                '' ORDER BY p.pos
            ) as new_state,
            COUNT(uc.pos) > 0 as has_unique  -- 检查本轮是否有唯一候选数
        FROM generate_series(1, 81) p(pos)
        LEFT JOIN unique_candidates uc ON uc.pos = p.pos
    ) calc
    WHERE 
        s.current_state LIKE '%0%'
        AND s.iteration < 10
        AND calc.has_unique  -- 只有本轮有唯一候选数才继续
        AND calc.new_state != s.current_state  -- 确保有变化
)
SELECT 
    id,
    puzzle,
    current_state as result,
    length(regexp_replace(current_state, '[^0]', '', 'g')) as unknown,
    iteration
FROM (
    SELECT 
        id,
        puzzle,
        current_state,
        iteration,
        row_number() OVER (PARTITION BY id ORDER BY iteration DESC) as rn
    FROM sudoku_solver
) ranked
WHERE rn = 1
ORDER BY id;
相关推荐
就叫_这个吧1 小时前
Redis从基础命令到核心机制简单介绍
数据库·redis·缓存
dear_bi_MyOnly2 小时前
【MyBatis 操作数据库】
java·数据库·学习·mybatis·学习方法
DBA_G3 小时前
南大通用GBase 8s数据库新存储引擎核心能力二
数据库·微服务·架构
圣光SG3 小时前
Java操作题练习(七)
java·开发语言·算法
衣乌安、4 小时前
数据库事务原理与回滚机制
数据库
Cx330_FCQ5 小时前
Tmux使用
服务器·git·算法
CodexDave5 小时前
PostgreSQL 明明有索引却选了 Nested Loop:从行数误判修正执行计划
数据库·postgresql·执行计划·扩展统计·nestedloop
拳里剑气6 小时前
C++算法:多源BFS
c++·算法·宽度优先·多源bfs
ysa0510307 小时前
【板子】短序列dp(换成维护更小常数维度的dp)
c++·笔记·算法·板子