Ogólny problem SAT (wartość logiczna) jest NP-zupełny. Ale 2-SAT , gdzie każda klauzula ma tylko 2 zmienne, jest w P . Napisz solver dla 2-SAT.
Wejście:
Instancja 2-SAT, zakodowana w CNF w następujący sposób. Pierwszy wiersz zawiera V, liczbę zmiennych logicznych i N, liczbę klauzul. Następnie następuje N linii, każda z 2 niezerowymi liczbami całkowitymi reprezentującymi literały klauzuli. Dodatnie liczby całkowite reprezentują podaną zmienną logiczną, a ujemne liczby całkowite reprezentują negację zmiennej.
Przykład 1
Wejście
4 5
1 2
2 3
3 4
-1 -3
-2 -4
który koduje wzór (x 1 lub x 2 ) i (x 2 lub x 3 ) i (x 3 lub x 4 ) i (nie x 1 lub nie x 3 ) i (nie x 2 lub nie x 4 ) .
Jedynym ustawieniem 4 zmiennych, które sprawiają, że cała formuła jest prawdziwa, jest x 1 = fałsz, x 2 = prawda, x 3 = prawda, x 4 = fałsz , więc twój program powinien wypisać pojedynczy wiersz
wynik
0 1 1 0
reprezentujące prawdziwe wartości zmiennych V (w kolejności od x 1 do x V ). Jeśli istnieje wiele rozwiązań, możesz wypisać dowolny niepusty ich podzbiór, po jednym w wierszu. Jeśli nie ma rozwiązania, musisz wydrukować UNSOLVABLE
.
Przykład 2
Wejście
2 4
1 2
-1 2
-2 1
-1 -2
wynik
UNSOLVABLE
Przykład 3
Wejście
2 4
1 2
-1 2
2 -1
-1 -2
wynik
0 1
Przykład 4
Wejście
8 12
1 4
-2 5
3 7
2 -5
-8 -2
3 -1
4 -3
5 -4
-3 -7
6 7
1 7
-7 -1
wynik
1 1 1 1 1 1 0 0
0 1 0 1 1 0 1 0
0 1 0 1 1 1 1 0
(lub dowolny niepusty podzbiór tych 3 wierszy)
Twój program musi obsłużyć wszystkie N, V <100 w rozsądnym czasie. Wypróbuj ten przykład, aby upewnić się, że Twój program może obsłużyć dużą instancję. Najmniejszy program wygrywa.
Odpowiedzi:
Haskell, 278 znaków
Nie brutalna siła. Działa w czasie wielomianowym. Szybko rozwiązuje trudny problem (60 zmiennych, 99 zdań):
I tak naprawdę większość tego czasu spędza na kompilowaniu kodu!
Pełny plik źródłowy, z przypadków testowych i szybkie check testuje dostępne .
Ungolf'd:
W wersji golf'd,
satisfy
iformat
zostały w całośćreduce
, chociaż w celu uniknięcia przejścian
,reduce
zwraca funkcję z listy zmiennych ([1..n]
) w wyniku strun.s
operator, lepszą obsługę nowej linii∮
jako operator!★
dlatego nazwa testu została zmieniona∈
źródło
J,
119103Przechodzi wszystkie przypadki testowe. Brak zauważalnego czasu działania.Edycja: Wyeliminowany,
(n#2)
a tym samymn=:
, jak również wyeliminowanie częściowych rang (dzięki, isawdrones). Tacit-> wyraźne i dyadyczne-> monadyczne, eliminując kilka kolejnych znaków.}.}.
do}.,
.Edycja: Ups. Jest to nie tylko rozwiązanie dla dużych N, ale
i. 2^99x
-> „błąd domeny”, aby dodać zniewagę głupocie.Oto oryginalna wersja bez golfisty i krótkie wyjaśnienie.
input=:0&".;._2(1!:1)3
obcina dane wejściowe na nowych liniach i analizuje liczby w każdej linii (kumulując wyniki na danych wejściowych).n
, macierz klauzul przypisana doclauses
(nie wymaga liczenia klauzul)cases
jest 0..2 n -1 zamienione na cyfry binarne (wszystkie przypadki testowe)(Long tacit function)"(_,1)
jest stosowany do każdego przypadku wcases
całościclauses
.<:@|@[{"(0,1)]
pobiera macierz operandów klauzul (poprzez pobranie abs (numer operacji) - 1 i usunięcie dereferencji ze sprawy, która jest tablicą)*@>:@*@[
dostaje tablicę w kształcie klauzuli bitów „nie nie” (0 za nie) przez nadużycie signum.=
stosuje bity nie do operandów.[:*./[:+./"1
ma zastosowanie+.
(i) do wierszy wynikowej macierzy i*.
(lub) do wyniku tego.*@+/
zastosowane do wyników daje 0, jeśli są wyniki i 1, jeśli nie ma.('UNSOLVABLE'"_)
`(#&cases) @.(*@+/) results
uruchamia stałą funkcję, podając „UNSOLVABLE”, jeśli 0, oraz kopię każdego elementu „rozwiązania” spraw, jeśli 1.echo
magiczne wydruki wyniku.źródło
"(_,1)
do"_ 1
.#:
działałby bez lewego argumentu.K - 89
Ta sama metoda, co rozwiązanie J.
źródło
Ruby, 253
Ale jest wolny :(
Po rozszerzeniu dość czytelny:
źródło
OCaml + Baterie,
438436 znakówWymaga dołączonych baterii OCaml najwyższego poziomu:
Muszę przyznać, że jest to bezpośrednie tłumaczenie rozwiązania Haskell. W mojej obronie, który z kolei jest bezpośrednią kodowania algorytmu prezentowany tutaj [PDF], z wzajemnego
satisfy
-eliminate
rekursji walcowanej do pojedynczej funkcji. Nieobjawiona wersja kodu pomniejszona o użycie baterii to:(
iota k
gra słów mam nadzieję, że wybaczysz).źródło