The Eight Queens Problem on Oracle SQL (Another Solution)

In response to this decision , I would like to indicate my own, somewhat simpler to perceive.

Like the author - I initially made a selection of all the possible combinations of queens:

select *
from
  (select level as A from Dual connect by level<=8) A
  cross join
  (select level as B from Dual connect by level<=8) B
  cross join
  (select level as C from Dual connect by level<=8) C
  cross join
  (select level as D from Dual connect by level<=8) D
  cross join
  (select level as E from Dual connect by level<=8) E
  cross join
  (select level as F from Dual connect by level<=8) F
  cross join
  (select level as G from Dual connect by level<=8) G
  cross join
  (select level as H from Dual connect by level<=8) H;


But then I decided to move in a slightly simpler way. Having formed an array using the indicated method, we, yes, got boards where in each vertical there is one queen. Accordingly, it is necessary to filter out only the horizontal and diagonal lines. And here I decided to use the design not x in (y,z). For contours, everything is simple:

where
  not A in (B,C,D,E,F,G,H)
  and not B in (A,C,D,E,F,G,H)
...
  and not H in (A,B,C,D,E,F,G)


This construction can also be reduced, since not A in (B) = not B in (A) , etc., we get:

where
  not A in (B,C,D,E,F,G,H)
  and not B in (C,D,E,F,G,H)
...
  and not G in (H)


Minus one line, and generally half the number of comparisons.

Further diagonals - in the same way, taking into account the line shift:

where
  not A in (B+1,C+2,D+3,E+4,F+5,G+6,H+7)
  and not B in (A-1,C+1,D+2,E+3,F+4,G+5,H+6)
...
  and not H in (A-7,B-6,C-5,D-4,E-3,F-2,G-1)


And just as not A in (B+1) = not B in (A-1) remove unnecessary comparisons:

where
  not A in (B+1,C+2,D+3,E+4,F+5,G+6,H+7)
  and not B in (C+1,D+2,E+3,F+4,G+5,H+6)
...
  and not G in (H+1)


To filter the second diagonal as well - just duplicate the code of the first diagonal with a complete replacement of the sign with the opposite:

where
  not A in (B-1,C-2,D-3,E-4,F-5,G-6,H-7)
  and not B in (C-1,D-2,E-3,F-4,G-5,H-6)
...
  and not G in (H-1)


Thus, we got three sets of conditions that must be observed to solve the problem.

To make everything look optimal and without zabrovanie in whereI grouped all the conditions:

where not A in (B,C,D,E,F,G,H,B+1,C+2,D+3,E+4,F+5,G+6,H+7,B-1,C-2,D-3,E-4,F-5,G-6,H-7)
  and not B in (C,D,E,F,G,H,C+1,D+2,E+3,F+4,G+5,H+6,C-1,D-2,E-3,F-4,G-5,H-6)
  and not C in (D,E,F,G,H,D+1,E+2,F+3,G+4,H+5,D-1,E-2,F-3,G-4,H-5)
  and not D in (E,F,G,H,E+1,F+2,G+3,H+4,E-1,F-2,G-3,H-4)
  and not E in (F,G,H,F+1,G+2,H+3,F-1,G-2,H-3)
  and not F in (G,H,G+1,H+2,G-1,H-2)
  and not G in (H,H+1,H-1)


And in the end, we format the output according to the requirements in the condition and add sorting so that the answer looks decent:

select 'a' || A A, 'b' || B B, 'c' || C C, 'd' || D D, 'e' || E E, 'f' || F F, 'g' || G G, 'h' || H H
from
  (select level as A from Dual connect by level<=8) A
  cross join
  (select level as B from Dual connect by level<=8) B
  cross join
  (select level as C from Dual connect by level<=8) C
  cross join
  (select level as D from Dual connect by level<=8) D
  cross join
  (select level as E from Dual connect by level<=8) E
  cross join
  (select level as F from Dual connect by level<=8) F
  cross join
  (select level as G from Dual connect by level<=8) G
  cross join
  (select level as H from Dual connect by level<=8) H
where not A in (B,C,D,E,F,G,H,B+1,C+2,D+3,E+4,F+5,G+6,H+7,B-1,C-2,D-3,E-4,F-5,G-6,H-7)
  and not B in (C,D,E,F,G,H,C+1,D+2,E+3,F+4,G+5,H+6,C-1,D-2,E-3,F-4,G-5,H-6)
  and not C in (D,E,F,G,H,D+1,E+2,F+3,G+4,H+5,D-1,E-2,F-3,G-4,H-5)
  and not D in (E,F,G,H,E+1,F+2,G+3,H+4,E-1,F-2,G-3,H-4)
  and not E in (F,G,H,F+1,G+2,H+3,F-1,G-2,H-3)
  and not F in (G,H,G+1,H+2,G-1,H-2)
  and not G in (H,H+1,H-1)
order by A, B, C, D, E, F, G, H;


PS It’s a pity that I did not participate in this Olympiad.

PPS The decision was made after reading the conditions of the problem, before writing his author did not peep.

Also popular now: