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:
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
This construction can also be reduced, since
Minus one line, and generally half the number of comparisons.
Further diagonals - in the same way, taking into account the line shift:
And just as
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:
Thus, we got three sets of conditions that must be observed to solve the problem.
To make everything look optimal and without zabrovanie in
And in the end, we format the output according to the requirements in the condition and add sorting so that the answer looks decent:
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.
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.