En este desafío, su tarea es construir un gráfico no dirigido a partir de una secuencia de directivas. Hay una directiva para cada entero no negativo, y cada uno transforma un gráfico dado en uno nuevo.
- Directiva
0
: agregue un nuevo nodo desconectado. - Directiva
1
: agregue un nuevo nodo y conéctelo a cada nodo existente. - Directiva
m > 1
: elimine todos los nodos cuyo grado (número de vecinos) es divisible porm
. Tenga en cuenta que0
es divisible por todosm
, por lo que los nodos desconectados siempre se eliminan.
Las directivas se aplican una por una, de izquierda a derecha, comenzando con el gráfico vacío. Por ejemplo, la secuencia [0,1,0,1,0,1,3]
se procesa de la siguiente manera, explicada usando un increíble arte ASCII. Comenzamos con el gráfico vacío y agregamos un vértice único según lo indicado por 0
:
a
Luego, agregue otro vértice y conéctelo al primero, como lo indique 1
:
a--b
Agregamos otro vértice desconectado y luego uno conectado, como lo indica 0
y 1
:
a--b c
\ \ /
`--d
Repetimos esto una vez más, según las indicaciones 0
y 1
:
,--f--e
/ /|\
a--b | c
\ \|/
`--d
Finalmente, eliminamos los vértices de grado 3 a
y b
, como lo indica 3
:
f--e
|\
| c
|/
d
Este es el gráfico definido por la secuencia [0,1,0,1,0,1,3]
.
Entrada
Una lista de enteros no negativos, que representa una secuencia de directivas.
Salida
El número de nodos en el gráfico definido por la secuencia.
Casos de prueba
[] -> 0
[5] -> 0
[0,0,0,11] -> 0
[0,1,0,1,0,1,3] -> 4
[0,0,0,1,1,1] -> 6
[0,0,1,1,0,0,1,1,2,5,7,0,1] -> 6
[0,0,1,1,1,1,5,1,4,3,1,0,0,0,1,2] -> 6
[0,0,1,1,0,0,1,1,5,2,3,0,0,1,1,0,0,1,1,3,4,0,0,1,1,2,1,1] -> 8
[0,0,1,1,0,0,1,1,2,5,7,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,8] -> 14
Reglas detalladas
Puede escribir una función o un programa completo. El conteo de bytes más corto gana. Las lagunas estándar no están permitidas. Por favor explique su algoritmo en su respuesta.
Ha pasado una semana, así que he aceptado la respuesta más corta. Si aparece uno aún más corto más tarde, actualizaré mi elección. Una mención de honor va a la respuesta de Peter Taylor , en la que se basaron varios otros, incluido el ganador.
fuente
Respuestas:
Pyth ,
3731Esta solución utiliza una función de reducción (
u
) para construir una lista, donde cada entrada corresponde a un nodo restante en la lista, y el valor de la entrada correspondiente a si el nodo se agregó originalmente bajo la directiva 0 o 1.G
es la variable acumuladora en la función reducir y contiene la lista mencionada anteriormente. Se inicializa a la lista vacía,Y
.H
toma el valor de cada miembro deQ
, la entrada, uno por uno. El resultado de la expresión se asigna aG
cada vez, yQ
se asigna la siguiente entrada deH
, y la expresión se vuelve a ejecutar.Para actualizar
G
correctamente, hay dos posibilidades, una para la directiva 0 o 1, y otra para las otras directivas. Estos casos se distinguen con el ternario.? ... <H2 ...
Si
H
es 0 o 1, entonces todo lo que tenemos que hacer es anexadosH
aG
.+GH
logra esto.De lo contrario, lo primero que se necesita es determinar, para cada nodo en el gráfico, cuántos vecinos tiene. Esto se logra en dos pasos:
Primero,
s>GT
cuenta el número de nodos en o después del nodo de entrada que son 1s. Todos estos están conectados al nodo de entrada, excepto que contaremos de más en 1 si el nodo de entrada es un 1.En segundo lugar, necesitamos el número de nodos anteriores al nodo de entrada que están conectados a él. Esto es 0 si el nodo de entrada es un 0, y el índice del nodo de entrada
T
, si el nodo de entrada es un 1. Este valor estaría dado por*@GTT
. Sin embargo, todavía existe el conteo excesivo de la primera sección que debe corregirse. Por lo tanto, calculamos en su*@GTtT
lugar, que es 1 menos si el nodo de entrada es un 1. Estos valores se suman, para dar el número de nodos conectados al nodo de entrada.% ... H
dará 0 si ese número es divisible porH
, y por lo tanto debe eliminarse, y de lo contrario no dará 0.f ... UG
por lo tanto, dará los índices de la entrada que no deben eliminarse, ya quef
es un filtro y 0 es falso.m@Gd
Convierte estos índices en los 0 y 1 de los nodos correspondientes.Finalmente, una vez que se encuentra la lista resultante de nodos etiquetados como 0 y 1, se calcula su longitud (
l
) y se imprime (implícita).Amplia idea gracias a @PeterTaylor.
fuente
GolfScript (53 bytes)
Demostración en línea
En realidad, todavía no he jugado al golf, pero he descubierto que no es muy fácil eliminar las variables
H
yT
, por lo que podría ser un mínimo local.Toma entrada en stdin en el formato
[0 1 2 3]
. Deja la salida en stdout.Sin golf:
fuente
CJam,
129 75 73 68 61 4642 bytesSolución basada en el algoritmo de Peter:
Expansión del código a seguir.
Solución anterior (61 bytes):
Toma información de STDIN como:
La salida es el número en STDOUT:
algoritmo :
U
que almacena la identificación del nodo que se va a agregar.0
, agregue[U]
a una lista de la lista1
, agregueU
a cada lista en la lista de listas y agregue otra lista compuesta por el primer elemento de cada una de las listas de listas yU
length - 1
divisibles porm
y sigo notando el primer elemento de esas listas. Después de filtrar, elimino toda la identificación eliminada de la lista restante de identificadores.Expansión de código :
Pruébalo aquí
fuente
Pyth,
888075 caracteresHe terminado. Quizás alguien más tenga algunos consejos de golf.
Y
es la lista de adyacencia del gráfico. Por razones de golf, también mantengo un nodo en esta lista, incluso después de que el nodo se eliminó (de lo contrario, tendría que actualizar todos los índices). Cada nodo se tiene como vecino. La listaJ
realiza un seguimiento de los nodos eliminados.Muestro los cambios de la lista de adyacencia en la entrada de ejemplo
[0,1,0,1,0,1,3]
:El algoritmo es bastante simple: iterar sobre todas las entradas, si input == 0: agrega un nuevo nodo consigo mismo como vecino, si input == 1: agrega un nuevo nodo con todos los nodos como vecinos (también los eliminados) y agrega este nodo a la lista de adyacencia de todos los nodos, si input> 1: determine los nodos con # vecino-1% input == 0 y agréguelos a
J
, en cada caso, actualice los vecinos de cada nodo usandoJ
. Al final imprima la longitud deY
menos la longitud de (el conjunto de)J
.Uso
Simplemente llame al script y dé como entrada
[0,1,0,1,0,1,3]
o algún otro caso de prueba.fuente
APL,
716555 caracteres{⍬≡⍺:≢⍵⋄r←1↓⍺⋄1<c←⊃⍺:r∇i⌿⍵/⍨i←0≠c|+/⍵⋄c:r∇∨⌿↑a(⍉a←⍵,1)⋄r∇0,0⍪⍵}∘(0 0⍴0)
{⍺←0 0⍴0⋄⍬≡⍵:≢⍺⋄(⍺{1<⍵:i⌿⍺/⍨i←×⍵|+/⍺⋄⍵:-⌿↑(1,1⍪⍺)1⋄0,0⍪⍺}⊃⍵)∇1↓⍵}
{g←0 0⍴0⋄(≢g)⊣{1<⍵:g⌿⍨←g/⍨←×⍵|+/g⋄(⊃g)-←g⍪⍨←g,⍨←⍵}¨2,⍵}
El gráfico se representa como una matriz de adyacencia booleana. Las filas / columnas se agregan y eliminan según sea necesario.
fuente
Pitón 2, 296
Cada nodo recibe una identificación única y se registran las identidades vecinas de cada nodo. Cuando la directiva es 0, se agrega una lista de vecinos vacía para el nuevo nodo. Cuando la directiva es 1, los identificadores de todos los nodos existentes se convierten en la lista de vecinos para el nuevo nodo, y todas las demás listas de vecinos se actualizan para incluir el nuevo ID de nodo. Para m> 1, los nodos con listas de vecinos que son múltiplos de m se eliminan de la lista de nodos y de todas las listas de vecinos. Gracias a @Optimizer por detectar un error en una versión anterior.
fuente
NetLogo, 160
La implementación es sencilla, lee cada símbolo y realiza la acción adecuada.
Puede ejecutar desde la línea de comandos como
f[0 0 1 1 0 0 1 1 2 5 7 0 1]
.fuente
Ruby
159157 ( demo )Esto define una función llamada
G
usando la sintaxis stabby-lambda. UseG[[0, 1]]
para llamarlo con comandos0
y1
.La implementación es bastante sencilla: hay una
Node
estructura (llamadaN
arriba) que contiene referencias a todos los nodos vinculados a través de lal
propiedad.G
crea nodos según sea necesario y manipula sus enlaces. Una versión legible está disponible aquí .fuente
CJam,
9997 bytesTodavía hay mucho por jugar al golf en esto. El algoritmo se basa en hacer un seguimiento de la matriz de adyacencia, pero representar la matriz vacía sin tener que tratarla especialmente me está dando dolores de cabeza.
Pruébalo aquí.
La entrada es una matriz de estilo CJam:
Puede usar este arnés de prueba para ejecutar todas las pruebas:
fuente
Pitón 2, 174
Esto probablemente todavía se puede jugar mucho al golf.
Usé un diccionario
g
para representar el gráfico. Los nodos están etiquetados por números y se asignan al conjunto de nodos adyacentes. Esto significa que cada actualización de un borde debe ejecutarse en sus dos puntos finales.Los nuevos índices de nodo se crean contando
n
. Cada vez, creo un nuevo nodo vacíon
. Para el comando0
, solo queda. Para el comando1
, está conectado entre sí a través del nodog[i]^={n};g[n]^={i}
; El uso de xor hace que el nodo no esté conectado a sí mismo. Para los comandos> 1, se elimina inmediatamente.El filtrado de los nodos cuyo grado es un múltiplo se realiza al encontrar primero los nodos que permanecen (
h
), y luegoand
con la lista de nodos y los vecinos de cada nodo.Finalmente, el número de entradas en el diccionario gráfico es la respuesta.
fuente
Mathematica, 223 bytes
Wow, esto resultó más de lo que esperaba.
Uso:
Aquí están los resultados de los casos de prueba:
Menos golfizado:
La forma en que esto funciona es representando el gráfico como una lista de "listas de vecinos".
Para la directiva 0 , solo agrego una lista vacía.
Para la directiva 1 , agrego una lista de todos los nodos anteriores y agrego el nuevo nodo a todos los nodos anteriores.
Para una directiva > 1 , eliminé los nodos especificados y actualicé el resto.
fuente