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,
satisfyyformatse ha incorporadoreduce, aunque para evitar pasarn,reducedevuelve una función de una lista de variables ([1..n]) al resultado de la cadena.sun 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)3corta 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)caseses 0..2 n -1 convertido a dígitos binarios (todos los casos de prueba)(Long tacit function)"(_,1)se aplica a cada casocasescon 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.[:*./[:+./"1se 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) @.(*@+/) resultsejecuta una función constante que proporciona 'NO RESUELVE' si 0, y una copia de cada elemento de 'solución' de casos si 1.echoimprime 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-eliminaterecursividad, todo en una sola función. Una versión no ofuscada del código, menos el uso de baterías, es:(El
iota kjuego de palabras espero que me perdones).fuente