Gwoździe Wilsona: rozwiązanie zagadki (metoda #3)

https://xpil.eu/05g

Dziś pokażę, jak można rozwiązać zagadkę o gwoździach Wilsona za pomocą SQL-a.

Rozwiązanie nadesłał jeden z Czytelników. Pozwoliłem sobie nieco sformatować i uporządkować kod, jednak ogólną logikę rozwiązania pozostawiłem bez zmian.

Kod wygląda tak:

;
WITH    licz10
          AS ( SELECT   0 x
               UNION ALL
               SELECT   licz10.x + 1
               FROM     licz10
               WHERE    licz10.x < 9 ) ,
        licz
          AS ( SELECT   l1.x + 10 * l2.x + 100 * l3.x x
               FROM     licz10 l1
                      , licz10 l2
                      , licz10 l3
               WHERE    l1.x + 10 * l2.x + 100 * l3.x <= 1000) ,
        cte
          AS ( SELECT   6 * m.x + 9 * s.x + 20 * d.x suma
                      , d.x d
                      , s.x s
                      , m.x m
               FROM     licz m
                      , licz s
                      , licz d
               WHERE    s.x <= 1
                        AND d.x <= 2) ,
        cte2
          AS ( SELECT   *
                      , CASE WHEN cte.suma - 1 <> LAG(cte.suma) OVER ( ORDER BY cte.suma ) THEN 1
                             ELSE 0
                        END * CASE WHEN cte.suma = LAG(cte.suma) OVER ( ORDER BY cte.suma ) THEN 0
                                   ELSE 1
                              END kandydat
               FROM     cte)
    SELECT  cte2.suma - 1 AS suma
    FROM    cte2
    GROUP BY cte2.suma
    HAVING  MAX(kandydat) > 0;

Wyniki:

suma
5
8
11
14
17
19
23
25
28
31
34
37
43
6000
6006
6009
6012
6015
6018
6021
6024
6027
6030
6033
6036
6042

Jak widać ostatni "nieduży" kandydat pojawia się przy 43, potem długo, długo nic, wreszcie kolejne "dziury" mamy przy sześciu tysiącach.

Czemu tak?

Otóż SQL to nie jest język analityczny, matematyczny, tylko proste głupiątko do żonglowania danymi. Jeżeli ograniczymy ilość szóstek, dziewiątek i dwudziestek, to siłą rzeczy niektóre kombinacje wymagające większych ich ilości nie zostaną znalezione i skrypt "wypluje" je jako kandydatury na wynik. Ale - jak się łatwo domyśleć - zwiększając limit z 1000 na, dajmy na to, 2000, zobaczymy, że te "dziury" w okolicach 6000 są tylko tymczasowe. I podobnie jak w jednym z poprzednich przykładów, gdzie losowaliśmy sobie gwoździe w Excelu, tak i tutaj widać wyraźnie, że zwiększanie limitu ciągle "zakleja" duże dziury, pozostawiając 43 nietknięte.

https://xpil.eu/05g

Leave a Comment

Komentarze mile widziane.

Jeżeli chcesz do komentarza wstawić kod, użyj składni:
[code]
tutaj wstaw swój kod
[/code]

Jeżeli zrobisz literówkę lub zmienisz zdanie, możesz edytować komentarz po jego zatwierdzeniu.