Antecedentes
Un árbol sin etiquetar puede verse así:
o
/ | \
o o o
| / \
o o o
Para linealizar este árbol, primero etiquetamos cada nodo o
con su número de nodos secundarios:
3
/ | \
1 0 2
| / \
0 0 0
y luego escribe los números en una lista de una manera impresionante, es decir, línea por línea y de izquierda a derecha:
[3, 1, 0, 2, 0, 0, 0]
Esta es una representación única e inequívoca del árbol de arriba, lo que significa que no hay dos árboles puros diferentes tendrán las mismas linealizaciones y que podemos reconstruir el árbol original de la lista.
Aunque cada árbol corresponde a una determinada lista de enteros, no cada lista de enteros representa un árbol linealizado válido: por ejemplo [2, 0, 0, 0]
, no representa un árbol válido, si intentamos deslinealizarlo terminamos con este árbol
[2,0,0,0] -> 2 [0,0,0] -> 2 [0,0] -> 2 [0]
/ \ / \ / \
0 0 0
pero todavía tengo una 0
izquierda en la lista y ningún lugar para ponerla. Del mismo modo, [2, 0]
tampoco es una linealización de árbol válida, ya que el árbol des-linealizado tiene un punto hijo vacío:
2
/ \
0
Tarea
Dada una lista entera, decida si es una linealización válida de un árbol utilizando la menor cantidad de bytes posible. Puede escribir un programa completo o una función.
Entrada: una lista no vacía de enteros no negativos.
Salida: un valor verdadero si la lista es una linealización de un árbol, un valor falso de lo contrario.
Casos de prueba
Verdad[0]
[2, 0, 0]
[1, 1, 1, 1, 1, 0]
[3, 1, 0, 2, 0, 0, 0]
[2, 0, 2, 2, 0, 0, 2, 0, 0]
[3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0]
[1, 5, 3, 0, 2, 1, 4, 0, 1, 0, 0, 2, 1, 0, 0, 1, 1, 0, 0, 0, 0, 2, 1, 0, 0, 1, 0]
Falsa
[0, 1]
[2, 0]
[2, 0, 0, 0]
[1, 0, 1]
[3, 2, 1, 0]
[2, 0, 0, 2, 0, 0]
[4, 1, 0, 3, 0, 0, 0, 0]
[4, 2, 0, 3, 1, 0, 0, 0, 0, 0]
{X0@{+\(_{\}&}/|!}
¿Yo creo que?@
.Laberinto , 17 bytes
Pruébalo en línea!
La salida de
-1
verdad es y la salida de falsa está vacía. Definir la verdad y la falsedad en Labyrinth es un poco complicado, porque las ramas de Labyrinth son principalmente ternarias. Sin embargo, la única forma de construir un condicional con dos ramas confiables, solo puede hacer esto:En este caso, consideraría avanzar hacia adelante falsamente (porque la dirección del movimiento no se ve afectada) y convertir la verdad. Estos corresponden a cero y no cero respectivamente. La razón por la que estoy usando una salida vacía para representar cero es que, si tuviera que canalizar la salida de nuevo a otro programa Labyrinth, el operador de entrada
?
realmente empujaría un cero si la entrada está vacía, por lo que considero que la cadena vacía es válida representación de cero.Explicación
El algoritmo sigue siendo el mismo que en mis respuestas de Mathematica y Retina, pero debido al flujo de control de Labyrinth, esta vez funciona un poco diferente:
-11
inicialmente, de modo que queremos que el contador sea negativo en toda la lista y llegue a cero en la última entrada. Esto realmente simplifica el flujo de control aquí.En lugar de construir la lista completa y verificar si contenía el valor incorrecto, hay tres posibles condiciones de terminación:
En cuanto al código real, comenzamos en la esquina superior izquierda. El
(
convierte el cero implícita en la parte superior de la pila en una-1
, que será el total acumulado. Luego ingresamos al ciclo principal muy apretado del programa+?-)"_,;+
:Eso deja solo los casos en los que hemos reducido el total acumulado a cero en algún momento. La IP se mueve hacia la esquina inferior derecha
,
y lee otro carácter para verificar si hemos llegado a EOF. De lo contrario, el valor será positivo y la IP gira hacia el oeste hacia@
y el programa termina. Si llegamos a EOF, la IP gira hacia el este e imprime-1
con!
. La IP se abrirá camino hacia la esquina inferior izquierda a@
través de un camino un poco extraño para finalizar el programa.fuente
Python, 82 bytes
Necesita más casos de prueba.
fuente
list
si este es Python 2 al menos, y al reorganizar e invertir la segunda condición, puede obtenerlo a 70 bytes:lambda l:all(l[x]<len(l)-x for x in range(len(l)))and len(l)==sum(l)+1
all
serx<len(l)-y for y,x in enumerate(l)
para guardar otros 2 bytes para llegar a 68.Pyth, 13 bytes
Comenzamos calculando el relleno actual del árbol en todos los puntos de la representación de entrada. Esa parte de la idea fue tomada en gran parte de Martin Ender, así que gracias a él.
sM._tMQ
Una vez que tenemos esta lista, verificamos si el primer índice que contiene
-1
(x..._1
) es la longitud de la entrada menos uno (q...tl(Q)
).¿No crees que funciona? ¡Inténtalo tú mismo!
fuente