71 lines
2.0 KiB
SQL
71 lines
2.0 KiB
SQL
WITH RECURSIVE
|
|
input(sud) AS (
|
|
VALUES('53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79')
|
|
),
|
|
|
|
digits(z, lp) AS (
|
|
VALUES('1', 1)
|
|
UNION ALL
|
|
SELECT CAST(lp+1 AS TEXT), lp+1 FROM digits WHERE lp<9
|
|
),
|
|
|
|
x(s, ind) AS (
|
|
SELECT sud, instr(sud, '.') FROM input
|
|
UNION ALL
|
|
SELECT
|
|
substr(s, 1, ind-1) || z || substr(s, ind+1),
|
|
instr(substr(s, 1, ind-1) || z || substr(s, ind+1), '.')
|
|
FROM x, digits AS z
|
|
WHERE ind>0
|
|
AND NOT EXISTS (
|
|
SELECT 1
|
|
FROM digits AS lp
|
|
WHERE z.z = substr(s, ((ind-1)/9)*9 + lp, 1)
|
|
OR z.z = substr(s, ((ind-1)%9) + (lp-1)*9 + 1, 1)
|
|
OR z.z = substr(s, (((ind-1)/3) % 3)*3
|
|
+ ((ind-1)/27)*27
|
|
+ lp + ((lp-1)/3)*6, 1)
|
|
)
|
|
),
|
|
|
|
solved(s) AS (
|
|
SELECT s FROM x WHERE ind=0
|
|
),
|
|
|
|
-- Build 9 pretty rows for both input and solved using digits.lp = 1..9
|
|
grid_rows(name, rn, line) AS (
|
|
SELECT 'input', d.lp,
|
|
substr(sud, (d.lp-1)*9+1, 3)
|
|
|| ' | ' ||
|
|
substr(sud, (d.lp-1)*9+4, 3)
|
|
|| ' | ' ||
|
|
substr(sud, (d.lp-1)*9+7, 3)
|
|
FROM input CROSS JOIN digits d
|
|
|
|
UNION ALL
|
|
|
|
SELECT 'solved', d.lp,
|
|
substr(s, (d.lp-1)*9+1, 3)
|
|
|| ' | ' ||
|
|
substr(s, (d.lp-1)*9+4, 3)
|
|
|| ' | ' ||
|
|
substr(s, (d.lp-1)*9+7, 3)
|
|
FROM solved CROSS JOIN digits d
|
|
),
|
|
|
|
-- Insert horizontal separators after rows 3 and 6 by computing an ordering key
|
|
grid_with_sep AS (
|
|
SELECT name, rn*2-1 AS ord, line FROM grid_rows
|
|
UNION ALL
|
|
SELECT name, rn*2 AS ord, '----+-----+----' FROM grid_rows WHERE rn IN (3,6)
|
|
)
|
|
|
|
-- Single final UNIONed selection, ordered by group + position
|
|
SELECT line FROM (
|
|
SELECT 1 AS grp, ord AS ord, line FROM grid_with_sep WHERE name='input'
|
|
UNION ALL
|
|
SELECT 2 AS grp, 0 AS ord, '' AS line
|
|
UNION ALL
|
|
SELECT 3 AS grp, ord AS ord, line FROM grid_with_sep WHERE name='solved'
|
|
) ORDER BY grp, ord;
|