Hashiwokakero (po japońsku „budowanie mostów”) to łamigłówka, w której zadaniem jest połączenie grupy wysp z mostami. Reguły są następujące:
- Mosty muszą przebiegać pionowo lub poziomo między dwiema wyspami.
- Mosty nie mogą się krzyżować.
- Para wysp może być połączona co najwyżej dwoma równoległymi mostami.
- Każda wyspa jest oznaczona numerem od 1 do 8 włącznie. Liczba mostów połączonych z wyspą musi być zgodna z liczbą na tej wyspie.
- Mosty muszą łączyć wyspy w jedną połączoną grupę.
Twoim zadaniem jest napisanie programu, który rozwiąże zagadki Hashiwokakero.
Możesz założyć, że daną łamigłówkę można rozwiązać i że istnieje tylko jedno rozwiązanie.
Program powinien być dość wydajny. Na przykład rozwiązanie poniższej układanki 25x25 nie powinno zająć więcej niż 10 minut na przeciętnym komputerze i nie powinno zajmować więcej niż gigabajt pamięci. Rozwiązanie mniejszych zagadek, takich jak 7x7, powinno zająć kilka sekund.
Wejście:
Puzzle zostaną podane jako mapa 2D znaków, z cyframi 1
do 8
reprezentujących wysp i przestrzeni reprezentujących wodę. W razie potrzeby linie zostaną wypełnione spacjami, aby uzyskać taką samą długość.
Wyspy zawsze będą oddzielone poziomo i pionowo co najmniej jednym kwadratem wody, aby między nimi był potencjalny most. W układance zawsze będą przynajmniej dwie wyspy.
Twój program powinien najlepiej czytać mapę puzzli ze standardowego wejścia, ale możesz podać alternatywną metodę wprowadzania, jeśli Twój język programowania tego wymaga.
Wynik:
Dane wyjściowe powinny być podobne do danych wejściowych, z wyjątkiem spacji zastępowanych w razie potrzeby mostkami. Mosty należy narysować przy użyciu znaków rysunkowych w polu Unicode ─
(U + 2500), │
(U + 2502), ═
(U + 2550) i ║
(U + 2551) w celu przedstawienia poziomych i pionowych pojedynczych i podwójnych mostów.
Jeżeli znaki Unicode są problemem, można używać znaków ASCII -
, |
, =
a H
zamiast tego.
Kryteria wygranej:
To jest kod golfowy. Wygrywa najkrótsze prawidłowe i rozsądnie wydajne rozwiązanie.
Przykłady:
Puzzle (7x7):
2 2 1
1 4 3
3 2
4
3 2 3
1
3 4 2
Rozwiązanie:
2─2──1
│1──4─3
3──2║ ║
│ │4 ║
│3─2║ 3
1║ ║ │
3──4─2
Puzzle (25x25):
2 2 2 2 1 1 2 2 2 2 2
1 3 5 4 4 2
2 2 4 5 5 4 2 2 1 3
2 1 1 3 3 2 2
3 4 4 4 4 5 4 3 2 3
2 4 5 4 2 3
2 1 4 2 4 3 1 1 2
2 1 3 1 1 6 4 2
3 2 4 3 6 3 2
2 2 3 3 2 5 2 4 3
2 1 1 2
1 3 3 3 3 5 8 7 6 5 4
2 3 1 1 2
1 1 5 1 4 5 6 3 1 2
1 1 2 2 3 4
3 5 4 4 3 3 8 7 5 1 2
2 3 1 2 2 1 1
2 2 2 2 5 7 6 3 3
3 3 6 3 5 3 2 2 2 3
2 1 2 3 2 2
3 4 6 4 5 5 3 3 5 1
2 1 2 2 1 1 3
2 1 1 2 3 6 5 2 2
2 3 4 4 4 2 1
2 2 2 2 2 2 2 1 1 3 2
Rozwiązanie:
2─2─2──2 1 1─2─2──2──2─2
│ │ │1─3═5══4══4─2│
2 2─4─5══5═4═2│2──1 │ │3
│ 2│ ║1│ 1─3═3─2│ │ 2║
│ ║3═4│4══4─4═5─4─3──2 │3
2 4═5─4│ │ │ ║ │ │2───3│
│2─1║ ║4─2│ 4─3 │ 1│ 1 │2
2│1─3 ║║ │1 ║1──6══4 │ 2│
│3─2──4║ 3══6─3 ║ │ │ │2
2│2═3 │3──2 │ ║ 5─2│ 4─3│
│2─1│ │ │ │ ║ ║ │1 ║ │2
│ 1─3─3─3─3─5═8═7═6──5═4│
2──3───1│1─2│ ║ │ ║ ││
1 │ 1──5─1││ 4─5─6─3─1│2
1│ │1──2║ │2 │ ║ ║ │3═4│
│3─5═4 │4──3│ 3═8═7═5│1│2
2│ │ ║ 3│ 1│2──2║ │ ║1│1│
│2 │ ║ ║2 │2──2│5═7═6─3─3
3│ 3─6─3│ 5═3 │2│ ║2│2─3│
║2 │ ║ │ ║ │ 1│2─3║2│ ║2
3│ 4═6──4─5─5──3─3─5││1║│
│2 │ │1 │ │2║2──1│ ║1││3│
2│ │ 1│ │ 1║2│3══6═5─2││2
│2─3──4═4──4─2│ │ │1│
2─2──2─2──2─2─2 1 1─3─2
1 1
wejście?1 1
, która jest prawidłową łamigłówką i powinna być traktowana poprawnie.Odpowiedzi:
Haskell, 1074 znaków
Początkowo miałem to jeszcze bardziej czysto japońskie, wdrażając również prymitywne funkcje w zakresie prostego dopasowywania wzorców i kombinacji list:
Haskell, 1192
działa na moim i5 za 3 minuty .
Skomentowana wersja:
źródło
Python, 1079 znaków
Kod wykonuje dość proste, wyczerpujące wyszukiwanie
S
, używając propagacji ograniczeń, aby uruchomić go w rozsądnym czasie.E
reprezentuje bieżący zestaw krawędzi, w formacie [od, do, delta, możliwe wagi] . od i do są identyfikatorami wysp, a delta wynosi 1 dla krawędzi poziomych lub W (= szerokość linii) dla krawędzi pionowych. możliwe wagi to podlista [0,1,2] kodująca aktualny znany stan tej krawędzi (0 = brak mostu, 1 = pojedynczy most, 2 = podwójny most).S
robi trzy rzeczy. Najpierw propaguje informacje, tak jakby jedna krawędź nie miała już ciężaru zerowego jako możliwej, a następnie wszystkie krawędzie, które ją przecinają, są eliminowane (ich możliwe wagi są ustawione na [0]). Podobnie, jeśli suma minimalnej wagi krawędzi powstających na wyspie jest równa wadze wyspy, wówczas wszystkie te krawędzie są ustawione na minimum.Po drugie,
S
sprawdza, czy wykres jest nadal połączony przy użyciu krawędzi innych niż [0] (Q
obliczenia).Wreszcie
S
wybiera krawędź, która wciąż nie jest w pełni określona i wywołuje się rekurencyjnie, ustawiając ją na jedną z pozostałych możliwości.Największy przykład zajmuje około 2 minut.
źródło
print(B);sys.exit(0)
C # -
660156612225Niezbyt dobrze golfowy. Wykorzystuje bibliotekę programowania ograniczeń z google or-tools. Buduje ograniczenia dla łącznej liczby krawędzi i eliminuje mostki krzyżowe, ale nieco trudniej jest zdefiniować ograniczenia, aby upewnić się, że wszystkie są ze sobą połączone. Dodałem logikę do komponentów przycinania 2 = 2 i 1-1, ale nadal muszę przejrzeć końcową listę (39 na dużej) i wyeliminować te, które nie są w pełni połączone. Działa dość szybko. Największy przykład zajmuje tylko kilka sekund. Nie golfowany:
źródło