El problema general de SAT (satisfacción booleana) es NP-completo. Pero 2-SAT , donde cada cláusula tiene sólo 2 variables, se encuentra en P . Escribe un solucionador para 2-SAT.
Entrada:
Una instancia de 2-SAT, codificada en CNF como sigue. La primera línea contiene V, el número de variables booleanas y N, el número de cláusulas. Luego siguen N líneas, cada una con 2 enteros distintos de cero que representan los literales de una cláusula. Los enteros positivos representan la variable booleana dada y los enteros negativos representan la negación de la variable.
Ejemplo 1
entrada
4 5
1 2
2 3
3 4
-1 -3
-2 -4
que codifica la fórmula (x 1 o x 2 ) y (x 2 o x 3 ) y (x 3 o x 4 ) y (no x 1 o no x 3 ) y (no x 2 o no x 4 ) .
La única configuración de las 4 variables que hace que toda la fórmula sea verdadera es x 1 = falso, x 2 = verdadero, x 3 = verdadero, x 4 = falso , por lo que su programa debería generar la línea única
salida
0 1 1 0
representando los valores de verdad de las variables V (en orden de x 1 a x V ). Si hay varias soluciones, puede generar cualquier subconjunto no vacío de ellas, una por línea. Si no hay solución, debe dar salida UNSOLVABLE
.
Ejemplo 2
entrada
2 4
1 2
-1 2
-2 1
-1 -2
salida
UNSOLVABLE
Ejemplo 3
entrada
2 4
1 2
-1 2
2 -1
-1 -2
salida
0 1
Ejemplo 4
entrada
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
salida
1 1 1 1 1 1 0 0
0 1 0 1 1 0 1 0
0 1 0 1 1 1 1 0
(o cualquier subconjunto no vacío de esas 3 líneas)
Su programa debe manejar todos los N, V <100 en un tiempo razonable. Pruebe este ejemplo para asegurarse de que su programa pueda manejar una gran instancia. El programa más pequeño gana.
Respuestas:
Haskell, 278 caracteres
No es fuerza bruta. Se ejecuta en tiempo polinomial. Resuelve el problema difícil (60 variables, 99 cláusulas) rápidamente:
Y, de hecho, ¡la mayor parte de ese tiempo se gasta compilando el código!
Archivo fuente completo, con casos de prueba y pruebas de verificación rápida disponibles .
Ungolf'd:
En la versión de golf'd,
satisfy
yformat
se ha incorporadoreduce
, aunque para evitar pasarn
,reduce
devuelve una función de una lista de variables ([1..n]
) al resultado de la cadena.s
un operador, mejor manejo de la nueva línea∮
como operador.★
así que ahora cambia el nombre de la prueba∈
fuente
J,
119103Pasa todos los casos de prueba. Sin tiempo de ejecución notable.Editar: Eliminado
(n#2)
yn=:
, por lo tanto , así como eliminar algunos parens de rango (gracias, isawdrones). Tácito-> explícito y diádico-> monádico, eliminando unos pocos caracteres más cada uno.}.}.
a}.,
.Editar: Whoops. No solo no es una solución para N grande, sino también
i. 2^99x
-> "error de dominio" para agregar insulto a la estupidez.Aquí está la versión original sin golf y una breve explicación.
input=:0&".;._2(1!:1)3
corta la entrada en las nuevas líneas y analiza los números en cada línea (acumulando los resultados en la entrada).n
, matriz de cláusulas asignada aclauses
(no necesita el recuento de cláusulas)cases
es 0..2 n -1 convertido a dígitos binarios (todos los casos de prueba)(Long tacit function)"(_,1)
se aplica a cada casocases
con todosclauses
.<:@|@[{"(0,1)]
obtiene una matriz de los operandos de las cláusulas (tomando abs (número de operación) - 1 y desreferenciando del caso, que es una matriz)*@>:@*@[
obtiene una matriz en forma de cláusula de bits 'no no' (0 para no) a través del abuso de signum.=
aplica los bits no a los operandos.[:*./[:+./"1
se aplica+.
(y) a través de las filas de la matriz resultante, y*.
(o) a través del resultado de eso.*@+/
aplicado a los resultados da un 0 si hay resultados y 1 si no hay ninguno.('UNSOLVABLE'"_)
`(#&cases) @.(*@+/) results
ejecuta una función constante que proporciona 'NO RESUELVE' si 0, y una copia de cada elemento de 'solución' de casos si 1.echo
imprime magia el resultado.fuente
"(_,1)
a"_ 1
.#:
funcionaría sin el argumento izquierdo.K - 89
El mismo método que la solución J.
fuente
Rubí, 253
Pero es lento :(
Bastante legible una vez expandido:
fuente
OCaml + Batteries,
438436 caracteresRequiere un OCaml Baterías incluidas de nivel superior:
Debo confesar que esta es una traducción directa de la solución de Haskell. En mi defensa, que a su vez es una codificación directa del algoritmo presentado aquí [PDF], con la mutua
satisfy
-eliminate
recursividad, todo en una sola función. Una versión no ofuscada del código, menos el uso de baterías, es:(El
iota k
juego de palabras espero que me perdones).fuente