Wprowadzenie
Przez wiele stuleci istniała pewna rzeka, która nigdy nie została zmapowana. Gildia Kartografów chce stworzyć mapę rzeki, jednak nigdy im się nie udało - z jakiegoś powodu wszyscy kartografowie, którzy wysłali ją na mapę rzeki, zostali zjedzeni przez dzikie zwierzęta w okolicy. Wymagane jest inne podejście.
Opis wejścia
Obszar jest prostokątną siatką komórek o długości m
i szerokości n
. Komórka w lewym dolnym rogu byłaby 0,0
, a komórka w prawym górnym rogu byłaby m-1,n-1
. m
i n
są podawane na wejściu jako krotka m,n
.
Dzięki zastosowaniu technik sondowania geograficznego na duże odległości zidentyfikowano położenie wysp wokół rzeki. Rozmiar wysp (tj. Ile komórek zajmuje wyspa) również został zidentyfikowany, ale kształt nie. Dostarczamy te informacje w krotce, s,x,y
gdzie s
jest wielkość wyspy, x
i y
są pozycjami x i y jednej konkretnej komórki tej wyspy. Każda krotka na wejściu jest oddzielona spacją, więc oto przykładowe wejście:
7,7 2,0,0 2,3,1 2,6,1 2,4,3 2,2,4 8,0,6 1,2,6 3,4,6
Aby lepiej zilustrować, oto dane wejściowe na wykresie:
y 6|8 1 3
5|
4| 2
3| 2
2|
1| 2 2
0|2
=======
0123456
x
Opis wyjścia
Wydrukuj mapę, używając znaków ASCII do reprezentacji części obszaru. Każda komórka będzie albo #
(lądem), albo .
(wodą). Mapa powinna przestrzegać następujących zasad:
- Definicja. Wyspa to ortogonalnie przylegająca grupa komórek lądowych, która jest całkowicie ograniczona przez komórki rzeczne i / lub granicę obszaru.
- Definicja. Rzeka to ortogonalnie przylegająca grupa komórek wodnych, która jest całkowicie ograniczona przez komórki lądowe i / lub granicę obszaru i nie zawiera „jezior” (2 x 2 obszary komórek wodnych).
- Rządzić . Mapa powinna zawierać dokładnie jedną rzekę.
- Rządzić . Każda ponumerowana komórka na wejściu powinna być częścią wyspy zawierającej dokładnie
s
komórki. - Rządzić . Każda wyspa na mapie musi zawierać dokładnie jedną z ponumerowanych komórek na wejściu.
- Rządzić . Istnieje jedna unikalna mapa dla każdego wejścia.
Oto wynik przykładowego wejścia:
#.#.##.
#....#.
#.##...
##..##.
###....
...##.#
##....#
Oto kolejne wejście i wyjście.
Wejście:
5,5 3,0,1 1,4,1 2,0,4 2,2,4 2,4,4
Wynik:
#.#.#
#.#.#
.....
###.#
.....
źródło
javascript:(_=>{var t=Game.nurikabe().task,m=t.length,n=t[0].length,s=[m,n];for(var i=0;i<m;i++)for(var j=0;j<n;j++)if(t[i][j]>=0)s+=' '+[t[i][j],i,j];puzzleContainerDiv.insertAdjacentHTML('beforeend','<hr><tt style=color:red>'+s+'</tt><hr>')})();void(0)
Odpowiedzi:
C + PicoSAT ,
2345995952 bajtówWypróbuj online!
(Ostrzeżenie: ten link TIO to 30-kilobajtowy adres URL, który zawiera zminimalizowaną kopię PicoSAT 965, więc może nie być w stanie załadować go w niektórych przeglądarkach, ale ładuje się przynajmniej w przeglądarce Firefox i Chrome.
Jak to działa
Inicjalizujemy solver SAT zmienną dla każdej komórki (lądowej lub wodnej) i tylko następujące ograniczenia:
Reszta ograniczeń jest trudna do zakodowania bezpośrednio w SAT, więc zamiast tego uruchamiamy solver, aby uzyskać model, uruchamiamy sekwencję przeszukiwania w pierwszej kolejności, aby znaleźć połączone regiony tego modelu, i dodajemy dodatkowe ograniczenia w następujący sposób:
Korzystając z interfejsu przyrostowego do biblioteki PicoSAT, możemy natychmiast ponownie uruchomić solver, w tym dodane ograniczenia, zachowując wszystkie poprzednie wnioski dokonane przez solver. PicoSAT daje nam nowy model i kontynuujemy iterację powyższych kroków, aż rozwiązanie będzie prawidłowe.
Jest to niezwykle skuteczne; rozwiązuje 15 × 15 i 20 × 20 instancji w ułamku sekundy.
(Dzięki Lopsy za zasugerowanie pomysłu interaktywnego ograniczania połączonych regionów w przyrostowym rozwiązaniu SAT, jakiś czas temu.)
Niektóre większe przypadki testowe z puzzle-nurikabe.com
Losowa strona twardych zagadek 15 × 15 ( 5057541 , 5122197 , 5383030 , 6275294 , 6646970 , 6944232 ):
Losowa strona 20 × 20 normalnych zagadek ( 536628 , 3757659 ):
źródło
GLPK , (niekonkurujące) 2197 bajtów
Jest to wpis niekonkurujący, as
Uratuję tutaj jeszcze nie ulepszoną, ale funkcjonalną wersję. W zależności od opinii, mogę spróbować ją skrócić + dodać wyjaśnienie, jeśli jest zainteresowanie. Jak dotąd nazwy ograniczeń służą jako dokumenty w miejscu.
Główną ideą jest zakodowanie ograniczenia „ciągłych wysp” poprzez wprowadzenie zachowanej zmiennej przepływu, która ma wstępnie określone źródło w miejscu podpowiedzi. Zmienna decyzyjna
is_island
odgrywa następnie rolę zlewozmywaków umieszczalnych. Dzięki zminimalizowaniu całkowitej sumy tego przepływu wyspy są zmuszone pozostać połączone w optymalny sposób. Inne ograniczenia raczej bezpośrednio wdrażają różne reguły. Zastanawia mnie to, że wciąż potrzebujęisland_fields_have_at_least_one_neighbor
.Wydajność tego preparatu nie jest jednak świetna. Przez bezpośrednie zjedzenie całej złożoności z dużą ilością ograniczeń, solver zajmuje prawie 15 sekund dla przykładu 15 x 15.
Kod (wciąż nie golfowy)
Dane problemu
5 x 5
7 x 7
15 x 15
Stosowanie
Zostały
glpsol
zainstalowane, modelu jako jeden plik (npriver.mod
), dane wejściowe w oddzielnym pliku (ów) (na przykład7x7.mod
). Następnie:To plus odrobina cierpliwości wydrukuje rozwiązanie w określonym formacie wyjściowym (wraz z „niektórymi” wynikami diagnostycznymi).
źródło
Python 3 , 1295 bajtów
Jest to rozwiązanie tylko do Pythona. Nie używa bibliotek i ładuje płytę poprzez standardowe wejście. Dalsze wyjaśnienia w przyszłości. To moja pierwsza próba tak dużego golfa. Na dole znajduje się link do skomentowanego i nie golfowego kodu.
Wypróbuj online!
Spójrz na kod bez golfa .
źródło