WITH
  symbols (d) AS (SELECT to_char(level) FROM dual CONNECT BY level <=  9)
, board   (i) AS (SELECT level          FROM dual CONNECT BY level <= 81)
, neighbors (i, j) AS (
    SELECT b1.i, b2.i
    FROM   board b1 INNER JOIN board b2
      ON   b1.i!= b2.i
           AND (
                    MOD(b1.i - b2.i, 9) = 0
                 OR CEIL(b1.i /  9) = CEIL(b2.i /  9)
                 OR CEIL(b1.i / 27) = CEIL(b2.i / 27) AND trunc(MOD(b1.i - 1, 9) / 3) = trunc(MOD(b2.i - 1, 9) / 3)
               )
  )
, r (str, pos) AS (
    SELECT :game, instr(:game, ' ')
      FROM  dual
    UNION ALL
    SELECT  substr(r.str, 1, r.pos - 1) || s.d || substr(r.str, r.pos + 1), instr(r.str, ' ', r.pos + 1)
      FROM  r INNER JOIN symbols s
        ON  r.pos > 0 AND NOT EXISTS (
                                       SELECT *
                                       FROM   neighbors n
                                       WHERE  r.pos = n.i AND s.d = substr(r.str, n.j, 1)
                                     )
  )
SELECT str
FROM   r
WHERE  pos = 0
;