On 2018/05/04 1:54 AM, Cezary H. Noweta wrote:
Hello,

At the beginning I would like to agree with that the problem is iterative rather then recursive one. However....

LOL, that might be the hackiest query I ever seen, but kudos mate, that's bloody marvellous!

I corrected the table to not have duplicate points, and then added some bits to visualize the points, which makes it easier to see what is happening - also just for fun :) (Might have to run it a couple times to get a point-set that actually passes)



  -- SQLite version 3.20.1  [ Release: 2017-08-24 ]  on SQLitespeed version 2.0.2.4.   -- ================================================================================================

DROP TABLE IF EXISTS points;

CREATE TABLE points(
  x INT, y INT, PRIMARY KEY (x,y)
);

WITH cte(x,y,n) AS (
  SELECT (random() % 10 + 10) % 10 + 1, (random() % 10 + 10) % 10 + 1, 1
  UNION ALL
  SELECT (random() % 10 + 10) % 10 + 1, (random() % 10 + 10) % 10 + 1, n + 1
    FROM cte
   WHERE n < 100
)
INSERT INTO points(x,y)
SELECT DISTINCT x, y FROM cte;


SELECT 'Y_'||y AS 'Points',
       MAX(CASE X WHEN  1 THEN ' * ' ELSE '   ' END) AS X_1,
       MAX(CASE X WHEN  2 THEN ' * ' ELSE '   ' END) AS X_2,
       MAX(CASE X WHEN  3 THEN ' * ' ELSE '   ' END) AS X_3,
       MAX(CASE X WHEN  4 THEN ' * ' ELSE '   ' END) AS X_4,
       MAX(CASE X WHEN  5 THEN ' * ' ELSE '   ' END) AS X_5,
       MAX(CASE X WHEN  6 THEN ' * ' ELSE '   ' END) AS X_6,
       MAX(CASE X WHEN  7 THEN ' * ' ELSE '   ' END) AS X_7,
       MAX(CASE X WHEN  8 THEN ' * ' ELSE '   ' END) AS X_8,
       MAX(CASE X WHEN  9 THEN ' * ' ELSE '   ' END) AS X_9,
       MAX(CASE X WHEN 10 THEN ' * ' ELSE '   ' END) AS X_10
  FROM points
 GROUP BY y
;


  -- Points | X_1 | X_2 | X_3 | X_4 | X_5 | X_6 | X_7 | X_8 | X_9 | X_10
  -- ------ | --- | --- | --- | --- | --- | --- | --- | --- | --- | ----
  -- Y_1    |  *  |     |     |  *  |  *  |     |     | |     |  *
  -- Y_2    |  *  |  *  |     |     |     |  *  |  *  |  * |     |
  -- Y_3    |  *  |     |  *  |  *  |  *  |  *  |  *  | |  *  |
  -- Y_4    |  *  |  *  |     |  *  |     |  *  |  *  |  * |     |
  -- Y_5    |  *  |     |  *  |     |  *  |  *  |  *  |  * |  *  |
  -- Y_6    |     |     |  *  |  *  |  *  |  *  |     |  * |  *  |  *
  -- Y_7    |  *  |  *  |  *  |  *  |  *  |     |  *  |  * |     |  *
  -- Y_8    |  *  |  *  |     |  *  |     |  *  |  *  | |  *  |
  -- Y_9    |     |  *  |  *  |  *  |  *  |  *  |  *  |  * |  *  |  *
  -- Y_10   |  *  |  *  |     |  *  |  *  |  *  |     |  * |  *  |  *

WITH
  params(nx, ny) AS (SELECT 5, 6),
  main(elem, rest) AS (
    SELECT NULL, (
      WITH
        state(clock, points, xaxis, yaxis, nxmin, nxmax, nymin, nymax) AS (
          SELECT
            0,
            (SELECT GROUP_CONCAT(x || ' ' || y) FROM points),
            (SELECT GROUP_CONCAT(x || ' ' || n) FROM (SELECT x, COUNT(x) n FROM points GROUP BY x)),             (SELECT GROUP_CONCAT(y || ' ' || n) FROM (SELECT y, COUNT(y) n FROM points GROUP BY y)),             (SELECT MIN(n) FROM (SELECT x, COUNT(x) n FROM points GROUP BY x)),             (SELECT MAX(n) FROM (SELECT x, COUNT(x) n FROM points GROUP BY x)),             (SELECT MIN(n) FROM (SELECT y, COUNT(y) n FROM points GROUP BY y)),             (SELECT MAX(n) FROM (SELECT y, COUNT(y) n FROM points GROUP BY y))
          UNION ALL
          SELECT
            (clock + 1) % 3,
            CASE clock WHEN 0 THEN
            (SELECT GROUP_CONCAT(x || ' ' || y) FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.points
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(elem AS INTEGER) x,
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) y
                FROM cte WHERE elem IS NOT NULL
            )
            WHERE (x NOT IN (
              SELECT x FROM (
                WITH
                  cte(elem, rest) AS (
                    SELECT NULL, state.xaxis
                    UNION ALL
                    SELECT
                      SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                      SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                    FROM cte
                    WHERE rest IS NOT NULL
                  )
                SELECT
                  CAST(elem AS INTEGER) x,
                  CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                  FROM cte WHERE elem IS NOT NULL
              ) WHERE n < (SELECT nx FROM params)
            )) AND (y NOT IN (
              SELECT y FROM (
                WITH
                  cte(elem, rest) AS (
                    SELECT NULL, state.yaxis
                    UNION ALL
                    SELECT
                      SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                      SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                    FROM cte
                    WHERE rest IS NOT NULL
                  )
                SELECT
                  CAST(elem AS INTEGER) y,
                  CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                  FROM cte WHERE elem IS NOT NULL
              ) WHERE n < (SELECT ny FROM params)
            ))) ELSE points END,
            CASE clock WHEN 1 THEN
            (SELECT GROUP_CONCAT(x || ' ' || n) FROM (SELECT x, COUNT(x) n FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.points
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(elem AS INTEGER) x
                FROM cte WHERE elem IS NOT NULL
            ) GROUP BY x)) ELSE xaxis END,
            CASE clock WHEN 1 THEN
            (SELECT GROUP_CONCAT(y || ' ' || n) FROM (SELECT y, COUNT(y) n FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.points
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) y
                FROM cte WHERE elem IS NOT NULL
            ) GROUP BY y)) ELSE yaxis END,
            CASE clock WHEN 2 THEN
            (SELECT MIN(n) FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.xaxis
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                FROM cte WHERE elem IS NOT NULL
            )) ELSE nxmin END,
            CASE clock WHEN 2 THEN
            (SELECT MAX(n) FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.xaxis
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                FROM cte WHERE elem IS NOT NULL
            )) ELSE nxmax END,
            CASE clock WHEN 2 THEN
            (SELECT MIN(n) FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.yaxis
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                FROM cte WHERE elem IS NOT NULL
            )) ELSE nymin END,
            CASE clock WHEN 2 THEN
            (SELECT MAX(n) FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.yaxis
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                FROM cte WHERE elem IS NOT NULL
            )) ELSE nymax END
          FROM state
          WHERE (SELECT nx FROM params) BETWEEN nxmin + 1 AND nxmax OR
                (SELECT ny FROM params) BETWEEN nymin + 1 AND nymax
        ) SELECT points FROM state WHERE nxmin >= (SELECT nx FROM params) AND nymin >= (SELECT ny FROM params)
    )
    UNION ALL
    SELECT
      SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
      SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
    FROM main
    WHERE rest IS NOT NULL
  ), res(x,y) AS (
    SELECT CAST(elem AS INTEGER),
           CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER)
      FROM main WHERE elem IS NOT NULL
  ), grid(gy) AS (
    SELECT 1
    UNION ALL
    SELECT gy+1 FROM grid WHERE gy<10
  )
SELECT 'Y_'||gy AS 'Points',
       MAX(CASE X WHEN  1 THEN ' * ' ELSE '   ' END) AS X_1,
       MAX(CASE X WHEN  2 THEN ' * ' ELSE '   ' END) AS X_2,
       MAX(CASE X WHEN  3 THEN ' * ' ELSE '   ' END) AS X_3,
       MAX(CASE X WHEN  4 THEN ' * ' ELSE '   ' END) AS X_4,
       MAX(CASE X WHEN  5 THEN ' * ' ELSE '   ' END) AS X_5,
       MAX(CASE X WHEN  6 THEN ' * ' ELSE '   ' END) AS X_6,
       MAX(CASE X WHEN  7 THEN ' * ' ELSE '   ' END) AS X_7,
       MAX(CASE X WHEN  8 THEN ' * ' ELSE '   ' END) AS X_8,
       MAX(CASE X WHEN  9 THEN ' * ' ELSE '   ' END) AS X_9,
       MAX(CASE X WHEN 10 THEN ' * ' ELSE '   ' END) AS X_10
  FROM grid
  LEFT JOIN RES ON RES.y = grid.gy
 GROUP BY gy
;


  -- Points | X_1 | X_2 | X_3 | X_4 | X_5 | X_6 | X_7 | X_8 | X_9 | X_10
  -- ------ | --- | --- | --- | --- | --- | --- | --- | --- | --- | ----
  -- Y_1    |     |     |     |     |     |     |     | |     |
  -- Y_2    |     |     |     |     |     |     |     | |     |
  -- Y_3    |  *  |     |  *  |  *  |  *  |  *  |  *  | |  *  |
  -- Y_4    |  *  |  *  |     |  *  |     |  *  |  *  |  * |     |
  -- Y_5    |  *  |     |  *  |     |  *  |  *  |  *  |  * |  *  |
  -- Y_6    |     |     |  *  |  *  |  *  |  *  |     |  * |  *  |
  -- Y_7    |  *  |  *  |  *  |  *  |  *  |     |  *  |  * |     |
  -- Y_8    |  *  |  *  |     |  *  |     |  *  |  *  | |  *  |
  -- Y_9    |     |  *  |  *  |  *  |  *  |  *  |  *  |  * |  *  |
  -- Y_10   |  *  |  *  |     |  *  |  *  |  *  |     |  * |  *  |

WITH
  params(nx, ny) AS (SELECT 5, 6),
  main(elem, rest) AS (
    SELECT NULL, (
      WITH
        state(clock, points, xaxis, yaxis, nxmin, nxmax, nymin, nymax) AS (
          SELECT
            0,
            (SELECT GROUP_CONCAT(x || ' ' || y) FROM points),
            (SELECT GROUP_CONCAT(x || ' ' || n) FROM (SELECT x, COUNT(x) n FROM points GROUP BY x)),             (SELECT GROUP_CONCAT(y || ' ' || n) FROM (SELECT y, COUNT(y) n FROM points GROUP BY y)),             (SELECT MIN(n) FROM (SELECT x, COUNT(x) n FROM points GROUP BY x)),             (SELECT MAX(n) FROM (SELECT x, COUNT(x) n FROM points GROUP BY x)),             (SELECT MIN(n) FROM (SELECT y, COUNT(y) n FROM points GROUP BY y)),             (SELECT MAX(n) FROM (SELECT y, COUNT(y) n FROM points GROUP BY y))
          UNION ALL
          SELECT
            (clock + 1) % 3,
            CASE clock WHEN 0 THEN
            (SELECT GROUP_CONCAT(x || ' ' || y) FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.points
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(elem AS INTEGER) x,
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) y
                FROM cte WHERE elem IS NOT NULL
            )
            WHERE (x NOT IN (
              SELECT x FROM (
                WITH
                  cte(elem, rest) AS (
                    SELECT NULL, state.xaxis
                    UNION ALL
                    SELECT
                      SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                      SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                    FROM cte
                    WHERE rest IS NOT NULL
                  )
                SELECT
                  CAST(elem AS INTEGER) x,
                  CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                  FROM cte WHERE elem IS NOT NULL
              ) WHERE n < (SELECT nx FROM params)
            )) AND (y NOT IN (
              SELECT y FROM (
                WITH
                  cte(elem, rest) AS (
                    SELECT NULL, state.yaxis
                    UNION ALL
                    SELECT
                      SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                      SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                    FROM cte
                    WHERE rest IS NOT NULL
                  )
                SELECT
                  CAST(elem AS INTEGER) y,
                  CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                  FROM cte WHERE elem IS NOT NULL
              ) WHERE n < (SELECT ny FROM params)
            ))) ELSE points END,
            CASE clock WHEN 1 THEN
            (SELECT GROUP_CONCAT(x || ' ' || n) FROM (SELECT x, COUNT(x) n FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.points
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(elem AS INTEGER) x
                FROM cte WHERE elem IS NOT NULL
            ) GROUP BY x)) ELSE xaxis END,
            CASE clock WHEN 1 THEN
            (SELECT GROUP_CONCAT(y || ' ' || n) FROM (SELECT y, COUNT(y) n FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.points
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) y
                FROM cte WHERE elem IS NOT NULL
            ) GROUP BY y)) ELSE yaxis END,
            CASE clock WHEN 2 THEN
            (SELECT MIN(n) FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.xaxis
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                FROM cte WHERE elem IS NOT NULL
            )) ELSE nxmin END,
            CASE clock WHEN 2 THEN
            (SELECT MAX(n) FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.xaxis
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                FROM cte WHERE elem IS NOT NULL
            )) ELSE nxmax END,
            CASE clock WHEN 2 THEN
            (SELECT MIN(n) FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.yaxis
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                FROM cte WHERE elem IS NOT NULL
            )) ELSE nymin END,
            CASE clock WHEN 2 THEN
            (SELECT MAX(n) FROM (
              WITH
                cte(elem, rest) AS (
                  SELECT NULL, state.yaxis
                  UNION ALL
                  SELECT
                    SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
                    SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
                  FROM cte
                  WHERE rest IS NOT NULL
                )
              SELECT
                CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) n
                FROM cte WHERE elem IS NOT NULL
            )) ELSE nymax END
          FROM state
          WHERE (SELECT nx FROM params) BETWEEN nxmin + 1 AND nxmax OR
                (SELECT ny FROM params) BETWEEN nymin + 1 AND nymax
        ) SELECT points FROM state WHERE nxmin >= (SELECT nx FROM params) AND nymin >= (SELECT ny FROM params)
    )
    UNION ALL
    SELECT
      SUBSTR(rest, 1, IFNULL(NULLIF(INSTR(rest, ','), 0) - 1, LENGTH(rest))),
      SUBSTR(rest, NULLIF(INSTR(rest, ','), 0) + 1)
    FROM main
    WHERE rest IS NOT NULL
  )
SELECT
  CAST(elem AS INTEGER) x,
  CAST(SUBSTR(elem, INSTR(elem, ' ')) AS INTEGER) y
  FROM main WHERE elem IS NOT NULL;


  --  x  |  y
  -- --- | ---
  --  5  |  6
  --  3  |  9
  --  1  |  10
  --  5  |  5
  --  9  |  5
  --  2  |  9
  --  3  |  5
  --  9  |  10
  --  1  |  8
  --  8  |  5
  --  4  |  6
  --  2  |  8
  --  4  |  4
  --  3  |  3
  --  7  |  5
  --  6  |  5
  --  5  |  9
  --  2  |  4
  --  7  |  4
  --  4  |  10
  --  6  |  8
  --  9  |  3
  --  9  |  6
  --  8  |  7
  --  7  |  9
  --  6  |  4
  --  5  |  3
  --  6  |  10
  --  4  |  8
  --  7  |  7
  --  1  |  3
  --  2  |  10
  --  5  |  7
  --  6  |  9
  --  7  |  8
  --  7  |  3
  --  1  |  7
  --  2  |  7
  --  4  |  9
  --  8  |  6
  --  8  |  10
  --  4  |  7
  --  8  |  9
  --  4  |  3
  --  6  |  3
  --  9  |  8
  --  1  |  4
  --  6  |  6
  --  3  |  7
  --  1  |  5
  --  9  |  9
  --  8  |  4
  --  5  |  10
  --  3  |  6

  -- 2018-05-04 03:00:41.383  |  [Success]    Script Success.
  -- 2018-05-04 03:00:41.385  |  [Success]    Transaction Rolled back.
  -- -------  DB-Engine Logs (Contains logged information from all DB connections during run)  ------   -- [2018-05-04 03:00:41.324] APPLICATION : Script E:\Documents\SQLiteAutoScript.sql started at 03:00:41.324 on 04 May.
  -- [2018-05-04 03:00:41.359] ERROR (284) : automatic index on res(y)
  -- ================================================================================================


_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to