Masalah umum SAT (boolean satisfiability) adalah NP-complete. Tapi 2-SAT , di mana setiap klausul hanya memiliki 2 variabel, adalah di P . Tulis solver untuk 2-SAT.
Memasukkan:
Contoh 2-SAT, dikodekan dalam CNF sebagai berikut. Baris pertama berisi V, jumlah variabel boolean dan N, jumlah klausa. Kemudian N baris mengikuti, masing-masing dengan 2 bilangan nol bukan mewakili literal klausa. Bilangan bulat positif mewakili variabel boolean yang diberikan dan bilangan bulat negatif mewakili negasi variabel.
Contoh 1
memasukkan
4 5
1 2
2 3
3 4
-1 -3
-2 -4
yang menyandikan rumus (x 1 atau x 2 ) dan (x 2 atau x 3 ) dan (x 3 atau x 4 ) dan (bukan x 1 atau tidak x 3 ) dan (bukan x 2 atau tidak x 4 ) .
Satu-satunya pengaturan dari 4 variabel yang membuat seluruh rumus menjadi benar adalah x 1 = salah, x 2 = benar, x 3 = benar, x 4 = salah , sehingga program Anda harus menampilkan satu baris
keluaran
0 1 1 0
mewakili nilai kebenaran dari variabel V (dalam urutan dari x 1 ke x V ). Jika ada beberapa solusi, Anda dapat menampilkan subset nonempty dari mereka, satu per baris. Jika tidak ada solusi, Anda harus mengeluarkan UNSOLVABLE
.
Contoh 2
memasukkan
2 4
1 2
-1 2
-2 1
-1 -2
keluaran
UNSOLVABLE
Contoh 3
memasukkan
2 4
1 2
-1 2
2 -1
-1 -2
keluaran
0 1
Contoh 4
memasukkan
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
keluaran
1 1 1 1 1 1 0 0
0 1 0 1 1 0 1 0
0 1 0 1 1 1 1 0
(atau setiap subset kosong dari 3 baris)
Program Anda harus menangani semua N, V <100 dalam waktu yang wajar. Coba contoh ini untuk memastikan program Anda dapat menangani contoh besar. Program terkecil menang.
Jawaban:
Haskell, 278 karakter
Bukan kekerasan. Berjalan dalam waktu polinomial. Memecahkan masalah sulit (60 variabel, 99 klausa) dengan cepat:
Dan sebenarnya, sebagian besar waktu dihabiskan untuk menyusun kode!
File sumber lengkap, dengan kasus uji dan tes periksa cepat tersedia .
Tidak Digolkan:
Dalam versi golf,
satisfy
danformat
telah dimasukkan ke dalamreduce
, meskipun untuk menghindari lewatn
,reduce
mengembalikan fungsi dari daftar variabel ([1..n]
) ke hasil string.s
operator, penanganan baris baru yang lebih baik∮
sebagai operator!★
jadi tes sekarang diganti namanya∈
sumber
J,
119103Lewati semua kasus uji. Tidak ada runtime yang terlihat.Sunting: Dieliminasi
(n#2)
dan dengan demikiann=:
, serta menghilangkan beberapa parens peringkat (terima kasih, isawdrones). Tacit-> eksplisit dan dyadic-> monadic, masing-masing menghilangkan beberapa karakter.}.}.
untuk}.,
.Edit: Whoops. Tidak hanya ini bukan solusi untuk N besar, tetapi
i. 2^99x
-> "kesalahan domain" untuk menambah penghinaan terhadap kebodohan.Inilah versi asli dan penjelasan singkat yang tidak dikolongkan.
input=:0&".;._2(1!:1)3
memotong input pada baris baru dan mem-parsing angka pada setiap baris (mengumpulkan hasil menjadi input).n
, matriks klausa ditugaskan untukclauses
(tidak perlu jumlah klausa)cases
adalah 0..2 n -1 dikonversi ke digit biner (semua kasus uji)(Long tacit function)"(_,1)
diterapkan untuk setiap kasuscases
dengan semuaclauses
.<:@|@[{"(0,1)]
mendapatkan matriks dari operan klausa (dengan mengambil abs (nomor op) - 1 dan dereferencing dari kasus, yang merupakan array)*@>:@*@[
mendapat array berbentuk klausa dari bit 'tidak tidak' (0 untuk tidak) melalui penyalahgunaan signum.=
menerapkan bit tidak ke operan.[:*./[:+./"1
berlaku+.
(dan) melintasi baris matriks yang dihasilkan, dan*.
(atau) melintasi hasil itu.*@+/
diterapkan pada hasil memberi 0 jika ada hasil dan 1 jika tidak ada.('UNSOLVABLE'"_)
`(#&cases) @.(*@+/) results
menjalankan fungsi konstan yang memberikan 'TIDAK DAPAT DIKECUALIKAN' jika 0, dan salinan dari setiap elemen 'solusi' dari kasus jika 1.echo
sulap-cetak hasilnya.sumber
"(_,1)
untuk"_ 1
.#:
akan bekerja tanpa argumen kiri.K - 89
Metode yang sama dengan solusi J.
sumber
Ruby, 253
Tapi itu lambat :(
Cukup mudah dibaca setelah diperluas:
sumber
Baterai OCaml +,
438436 karakterMembutuhkan Baterai OCaml Termasuk tingkat atas:
Saya harus akui, ini adalah terjemahan langsung dari solusi Haskell. Dalam pembelaan saya, yang pada gilirannya adalah pengkodean langsung dari algoritma yang disajikan di sini [PDF], dengan saling
satisfy
-eliminate
rekursi digulung menjadi satu fungsi. Versi kode yang tidak dikobarkan, dikurangi penggunaan Baterai, adalah:(permainan
iota k
kata yang saya harap Anda akan memaafkan).sumber