Evo i moje resenje, radi i u MS SQL 2000. Lici mi da je prilicno standardan SQL, pa bi trebalo da radi i kojekuda drugo.
Radio sam od kuce, bez gledanja u originalni tekst mozgalice pa se moje tabele neznatno razlikuju od originalnih.
Kreirao sam dve tabele, Timovi i Brojevi:
Code:
CREATE TABLE Timovi
(TimID int PRIMARY KEY
, ImeTima varchar(50) UNIQUE
)
GO
INSERT INTO Timovi VALUES (1,'Zvesda')
INSERT INTO Timovi VALUES (2,'Partizan')
INSERT INTO Timovi VALUES (3,'Radnicki Nis')
INSERT INTO Timovi VALUES (4,'Sloboda Tuzla')
INSERT INTO Timovi VALUES (5,'Hajduk sa Liona')
INSERT INTO Timovi VALUES (6,'OFK Beograd')
INSERT INTO Timovi VALUES (7,'Barcelona')
INSERT INTO Timovi VALUES (8,'Inter')
CREATE TABLE BRojevi (Broj int PRIMARY KEY)
U brojeve sam uneo brojeve od 0 do 1000. vazno je da je od nule, a ne od jedinice.
Isti algoritam koji je negyxo resio sa WITH, ja sma resio sa dva-tri view-a.
Code:
CREATE VIEW Sablon AS
SELECT
Utakmica = Pos + 1
, Domacin_Pos = Pos
, Gost_Pos = (SELECt COUNT(*) FROM Timovi) - Pos - 1
FROM
(
SELECT Broj AS Pos FROM Brojevi
WHERE Broj <= ((SELECT COUNT(*) FROM Timovi)-1)
) AS P
WHERE Pos < (SELECt COUNT(*) FROM Timovi)/2
GO
SELECT
S.*
FROM Sablon AS S
Utakmica Domacin_Pos Gost_Pos
----------- ----------- -----------
1 0 7
2 1 6
3 2 5
4 3 4
(4 row(s) affected)
Timovo od2 do 8 treba da se rotiraju na pozicijama 0 do 7. Za svako kolo odnos pozicija timova ostaje isti, i to nam daje view "Sablon".
Rotiranje obezbedjuje view "Pozicije"
Code:
CREATEVIEW Pozicije AS
-- pozicije po kolima:
SELECT Kolo, Tim, Pos = CASE
WHEN Pos >= (SELECT COUNT(*) FROM Timovi)
THEN Pos + 1 - (SELECT COUNT(*) FROM Timovi)
ELSE Pos
END
FROM
(
--- Pozicija za im 1 je uvek Pos(Tim=1) = 0:
SELECT Kolo = Broj, Tim=1, Pos = 0
FROM Brojevi
WHERE Broj <= (SELECt COUNT(*) FROM Timovi)-1
AND Broj > 0
UNION
-- Pozicije ostalih timova
SELECT Kolo = Broj, Tim= TimID, Pos = TimID + Broj-2
FROM Timovi AS T, Brojevi AS B
WHERE TimID > 1
AND Broj <= (SELECt COUNT(*) FROM Timovi)-1
AND Broj > 0
) AS U
GO
SELECT * FROM Pozicije
Kolo Tim Pos
----------- ----------- -----------
1 1 0
2 1 0
3 1 0
4 1 0
5 1 0
6 1 0
7 1 0
1 2 1
1 3 2
1 4 3
1 5 4
1 6 5
1 7 6
1 8 7
2 2 2
2 3 3
2 4 4
2 5 5
2 6 6
2 7 7
2 8 1
Napisite na papiru rezultat kverija "Sablon". Tmove sa rezultata kverija "Pozicije" smestite na odgovarajuce pozicije u ispisanom sablonu. Ako pazljivo posmatrate rezultat videcete da tim 1 ostale u levom gornjem uglu sablona, a ostali timovi su se pomerili kruzno za po jednu poziciju u smeru suprotnom od kazaljke na satu.
Sada je potrebno da od view-a "Pozicije" napravimo raspored utakmica u poznatom obliku:
Code:
CREATE VIEW Utakmice AS
(
SELECT
D.Kolo, D.Utakmica, D.imeTima AS Domacin, G.ImeTima AS Gost
FROM
(
--- domacini po kolima:
SELECT
P.Kolo
, S.Utakmica
, P.Pos
, P.Tim
, T.ImeTima
FROM Pozicije AS P
JOIN Sablon AS S ON P.Pos = S.Domacin_Pos
JOIN Timovi AS T ON P.Tim = T.TimID
) AS D
JOIN
(
-- Gosti po kolima ---
SELECT
P.Kolo
, S.Utakmica
, P.Pos
, P.Tim
, T.ImeTima
FROM Pozicije AS P
JOIN Sablon AS S ON P.Pos = S.Gost_Pos
JOIN Timovi AS T ON P.Tim = T.TimID
) AS G
ON D.Kolo = G.Kolo AND D.Utakmica = G.Utakmica
)
GO
SELECT * FROM Utakmice
ORDER BY Kolo, Utakmica
Kolo Utakmica Domacin Gost
----------- ----------- -------------------------------------------------- --------------------------------------------------
1 1 Zvesda Inter
1 2 Partizan Barcelona
1 3 Radnicki Nis OFK Beograd
1 4 Sloboda Tuzla Hajduk sa Liona
2 1 Zvesda Barcelona
2 2 Inter OFK Beograd
2 3 Partizan Hajduk sa Liona
2 4 Radnicki Nis Sloboda Tuzla
3 1 Zvesda OFK Beograd
3 2 Barcelona Hajduk sa Liona
3 3 Inter Sloboda Tuzla
3 4 Partizan Radnicki Nis
Ovo vec izgleda jako blizu pravom resenju. Pravo resenje zahteva da timovi budu naizmenicno gosti i domacini, ako je moguce. Posto je broj kola neparan, neko ce morati da bude gost vise puta a neko ce biti domacin vise puta. A u drugom delu sezone sbve se menja. Sa porastom broja timova, odnos broja gostovanja i broja utakmica na svom terenu tezi da se uproseci. Za 16-18 timova prakticno s cini da je broj gostovanja gotovo isti za sve timove. Da probamo:
Code:
SELECT
Kolo
, Utakmica
, Parnepar = Kolo % 2
, Tim_Domacin = CASE WHEN Kolo % 2 = 0 THEN Gost ELSE Domacin END
, Tim_Gost = CASE WHEN Kolo % 2 = 0 THEN Domacin ELSE Gost END
FROM Utakmice
ORDER BY
Kolo
, Utakmica
-- rezultat:
Kolo Utakmica Parnepar Tim_Domacin Tim_Gost
----------- ----------- ----------- -------------------------------------------------- -----------------------------------
1 1 1 Zvesda Inter
1 2 1 Partizan Barcelona
1 3 1 Radnicki Nis OFK Beograd
1 4 1 Sloboda Tuzla Hajduk sa Liona
2 1 0 Barcelona Zvesda
2 2 0 OFK Beograd Inter
2 3 0 Hajduk sa Liona Partizan
2 4 0 Sloboda Tuzla Radnicki Nis
3 1 1 Zvesda OFK Beograd
3 2 1 Barcelona Hajduk sa Liona
3 3 1 Inter Sloboda Tuzla
3 4 1 Partizan Radnicki Nis
4 1 0 Hajduk sa Liona Zvesda
4 2 0 Sloboda Tuzla OFK Beograd
4 3 0 Radnicki Nis Barcelona
4 4 0 Partizan Inter
Prazne linije izmedju kola sam ubacio rucno, da se bolje vidi. Naravno da to moze i kroz kveri, ali to nije poenta mozgalice.
Ima li drugih pokusaja? Cini mi se da je najveci problem naci algoritam za rotiranje timova koji daje ono sto nam treba - da se u svakom kolu svaki tim pojavi tacno jednom. Mozda kolege sa foruma Matematika mogu da pomognu oko algoritma za rotiranje?
:-)