Fondo
En el momento de escribir esto, el problema P vs NP aún no se ha resuelto, pero es posible que haya oído hablar del nuevo artículo de Norbert Blum que afirma que P! = NP, que ya se sospecha que es erróneo (pero ya veremos).
El problema discutido en este documento es el problema de la camarilla . Al menos eso es lo que leo en un artículo de periódico, así que corrígeme si me equivoco, pero en cualquier caso, me gustaría que escribieras un programa que resuelva la siguiente variante:
La tarea
Supongamos que tenemos una escuela grande con muchos estudiantes. Cada uno de estos estudiantes tiene algunos amigos en esta escuela. Una camarilla de estudiantes es un grupo compuesto solo por estudiantes que son amigos entre sí .
Su programa recibirá pares de estudiantes que son amigos como entrada. A partir de esta información, el programa debe encontrar el tamaño de la camarilla más grande . Los estudiantes se identifican por ID enteros .
Si prefiere términos matemáticos, esto significa que está alimentado los bordes de un gráfico no dirigido, identificado por dos nodos cada uno.
Entrada
Su entrada será una lista no vacía de pares enteros positivos, por ejemplo [[1,2],[2,5],[1,5]]
. Puede tomar esta entrada en cualquier forma sensata, por ejemplo, como una matriz de matrices, como líneas de texto que contienen dos números cada una, etc.
Salida
El resultado esperado es un número único n >= 2
: el tamaño de la camarilla más grande. Con el ejemplo de entrada anterior, el resultado sería 3
, ya que todos los estudiantes ( 1
, 2
y 5
) son amigos entre sí.
Casos de prueba
[[1,2]]
=> 2
[[1,2],[3,1],[3,4]]
=> 2
[[1,2],[2,5],[1,5]]
=> 3
[[2,5],[2,3],[4,17],[1,3],[7,13],[5,3],[4,3],[4,1],[1,5],[5,4]]
=> 4 (the largest clique is [1,3,4,5])
[[15,1073],[23,764],[23,1073],[12,47],[47,15],[1073,764]]
=> 3 (the largest clique is [23,764,1073])
[[1296,316],[1650,316],[1296,1650],[1296,52],[1650,711],[711,316],[1650,52],
[52,711],[1296,711],[52,316],[52,1565],[1565,1296],[1565,316],[1650,1565],
[1296,138],[1565,138],[1565,711],[138,1650],[711,138],[138,144],[144,1860],
[1296,1860],[1860,52],[711,1639]]
=> 6 (the largest clique is [52,316,711,1296,1565,1650])
Puede usar esta implementación de referencia (estúpida) (imprime una salida adicional con una -d
marca) para verificar los resultados de otros casos de prueba.
Las normas
- Su programa no necesita un resultado definido en una entrada no válida. Entonces puedes asumir que:
- siempre obtendrá al menos un par de ID
- cada par consta de dos ID diferentes
- ningún par aparece dos veces (intercambiar los lugares de las ID seguiría siendo el mismo par)
- Su algoritmo no puede establecer un límite superior en el tamaño de entrada. Por supuesto, las limitaciones y limitaciones puramente técnicas establecidas por su idioma / entorno (como el tamaño de la pila, el tiempo de cálculo, etc.) son inevitables.
- Las lagunas estándar están prohibidas.
- Este es el código de golf , por lo que gana el código más corto, medido en bytes.
- Si su algoritmo tiene una complejidad de tiempo polinomial, obtiene
-1
una puntuación inmediata independientemente del tamaño de su código, pero en ese caso, es posible que desee enviar su solución a otro lugar. ;)
fuente
-1
es bien merecido ;)Respuestas:
Jalea ,
15 1816 bytes+3 bytes para corregir errores en mi método.
-2 bytes gracias a millas (observando que n × (n-1) ÷ 2 = nC2 )
Un enlace monádico que toma la lista de amistades (bordes) y devuelve un número entero.
Pruébalo en línea! forma el conjunto de potencia de los bordes en la memoria, por lo que es ineficiente tanto en espacio como en tiempo (sí, eso es O (2 n ) amigos).
¿Cómo?
fuente
Mathematica, 34 bytes
Básicamente, FindClique hace el trabajo y "encuentra una camarilla más grande en el gráfico g".
Todo lo demás está convirtiendo input-list en graph
Entrada
Salida
Entrada
Salida
Gracias @ Kelly Lowder para -10 bytes
fuente
Tr[1^#&@@FindClique[#<->#2&@@@#]]&
FindClique
ಠ ___ ಠJalea , 20 bytes
Pruébalo en línea!
Por supuesto, esto no merece el millón: p
Esto hubiera vencido a Pyth, si no fuera por el
µ(...)µ
y 2 bytesÐf
.fuente
J , 36 bytes
Pruébalo en línea!
Se ejecuta en el tiempo O (2 n ) donde n es el número de pares.
Una solución más rápida para 65 bytes es
Pruébalo en línea!
Explicación
fuente
Pyth, 19 bytes
Pruébalo aquí
fuente
Python 2 , 180 bytes
Pruébalo en línea!
-2 gracias a shooqie .
-1 gracias al Sr. Xcoder .
-3 gracias a recursivo .
fuente
len
a una variable(x not in y)
significa0**(x in y)
.0**
con-~-
.Pyth, 28 bytes
Pruébalo en línea
Explicación
fuente
Python 3 ,
162159bytesPruébalo en línea!
La función c toma vértices en forma de un conjunto de tuplas
ordenadas({(x, y), ...} donde x es menor que y).Una función llamada "entrada" está en el encabezado TIO para probar con datos en una lista de formato de listas sin clasificar. Si camarilla, devuelve longitud. Si no es camarilla, devuelve el tamaño máximo de camarilla de los vértices, menos un vértice por cada vértice en los vértices. Supera el tiempo en el último caso de prueba en TIOActualización: se agregó la porción "o (z, y) en x" para eliminar la dependencia de la clasificación "f = lambda x: {i para s en x para i en s}" en lugar de itertools.chain envuelto en el conjunto.
-minus 3 bytes gracias a @Jonathan Allen
fuente
c
, por lo que puede eliminarloc=
(debe colocarloc=\
al final del encabezado y colocarlolambda
en la parte superior del bloque de código para TIO)s
y reemplazars(...)
con{*...}
lo que permite la eliminación de algunos espacios también.05AB1E , 19 bytes
Pruébalo en línea!
fuente
Jalea , 28 bytes
Pruébalo en línea!
Solución más rápida que puede resolver el último caso de prueba en un segundo en TIO.
fuente
n
solo puede aparecer en las bases :)Java + Guava 23.0, 35 + 294 = 329 bytes
Este algoritmo no es un gráfico, sino que genera todas las combinaciones de pares, de un tamaño específico. Alimento todas las combinaciones de pares en un conjunto múltiple y verifico que todas tengan el tamaño esperado (el número de entradas únicas: 1). Si lo hacen, encontré una camarilla y busco una más grande.
De la biblioteca de guayaba, uso el nuevo
combinations
método y el tipo de colección de herramientasMultiset
.Sin golf
fuente
x
es polinomial " <- ¿estás seguro? Supongo que ese es el método utilizado . El valor de retorno esAbstractSet
con un iterador, y el siguientefor
ciclo llamará a este iteradorx!
veces si no me equivoco ...x < n
(conn
el tamaño completo del conjunto de entrada)n!/(x!(n-x)!)
, todavía no sea polinomial :)combinations
método que esX^n
(que es completamente posible), puedo obtenerlo? Mientras tanto, elimino mi reclamo de "-1".Python 2 , 102 bytes
Pruébalo en línea!
fuente
Código de máquina 6502 (C64),
774703 bytes(Acabo de tener que hacer esto, mi C64 puede hacer todo ... jeje)
hexdump:
Demostración en línea
Uso: Comience con
sys49152
, luego ingrese los pares uno por línea como p. Ej.Backsapce no se maneja durante la entrada (pero si la usa
vice
, simplemente copie y pegue su entrada en el emulador). Ingrese una línea vacía para comenzar el cálculo.Esto es demasiado grande para publicar una lista explicativa de desensamblaje aquí, pero puede explorar la fuente de ensamblaje de estilo ca65 . El algoritmo es muy ineficiente, genera todas las permutaciones posibles de los nodos y con cada uno de estos crea una camarilla con avidez al verificar todos los bordes. Esto permite una eficiencia de espacio de O (n) (algo importante en una máquina con esta pequeña RAM), pero tiene una eficiencia de tiempo de ejecución horrible (*) . Los límites teóricos son de hasta 256 nodos y hasta 8192 aristas.
Hay una versión más grande (
883805 bytes) con mejores características:Demostración en línea
Examinar fuente
(*) El último caso de prueba toma entre 12 y 20 horas (estaba durmiendo cuando finalmente terminó). Los otros casos de prueba terminan en el peor en unos minutos.
fuente