Contexte
Un arbre non étiqueté peut ressembler à ceci:
o
/ | \
o o o
| / \
o o o
Pour linéariser cet arbre, nous étiquetons d'abord chaque nœud o
avec son nombre de nœuds enfants:
3
/ | \
1 0 2
| / \
0 0 0
puis écrivez les nombres dans une liste d'une manière haletante, ce qui signifie ligne par ligne et de gauche à droite:
[3, 1, 0, 2, 0, 0, 0]
Il s'agit d'une représentation unique et sans ambiguïté de l'arbre ci-dessus, ce qui signifie que deux arbres purs différents n'auront pas les mêmes linéarisations et que nous pouvons reconstruire l'arbre d'origine à partir de la liste.
Bien que chaque arbre corresponde à une certaine liste d'entiers, chaque liste d'entiers ne représente pas un arbre linéarisé valide: par exemple [2, 0, 0, 0]
ne représente pas un arbre valide, si nous essayons de le linéariser, nous nous retrouvons avec cet arbre
[2,0,0,0] -> 2 [0,0,0] -> 2 [0,0] -> 2 [0]
/ \ / \ / \
0 0 0
mais ont encore une 0
gauche dans la liste et nulle part où le mettre. De même [2, 0]
, la linéarisation d'arbre n'est pas non plus valide, car l'arbre dé-linéarisé a une tache enfant vide:
2
/ \
0
Tâche
Étant donné une liste entière, décidez s'il s'agit d'une linéarisation valide d'un arbre en utilisant le moins d'octets possible. Vous pouvez écrire un programme complet ou une fonction.
Entrée: une liste non vide d'entiers non négatifs.
Sortie: une valeur vraie si la liste est une linéarisation d'un arbre, une valeur fausse sinon.
Cas de test
Truthy[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]
Falsy
[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@{+\(_{\}&}/|!}
Je pense?@
.Labyrinthe , 17 octets
Essayez-le en ligne!
La sortie
-1
vraie est la sortie fausse est vide. Définir le vrai et le faux dans le Labyrinthe est un peu délicat, car les branches du Labyrinthe sont principalement ternaires. Cependant, la seule façon de construire un conditionnel avec deux branches fiables, vous ne pouvez que le faire:Dans ce cas, j'envisagerais d'avancer droit devant la fausseté (car la direction du mouvement n'est pas affectée) et de devenir véridique. Celles-ci correspondent respectivement à zéro et non nul. La raison pour laquelle j'utilise une sortie vide pour représenter zéro est que, si vous redirigez la sortie vers un autre programme Labyrinth, l'opérateur d'entrée
?
poussera en fait un zéro si l'entrée est vide, donc je considère que la chaîne vide est valide représentation de zéro.Explication
L'algorithme est toujours le même que dans mes réponses Mathematica et Retina, mais en raison du flux de contrôle de Labyrinth, il fonctionne un peu différemment cette fois:
-11
initialement, de sorte que nous voulons que le compteur soit négatif dans toute la liste et que nous frappions zéro sur la dernière entrée. Cela simplifie en fait le flux de contrôle ici.Au lieu de construire la liste complète et de vérifier si elle contient la mauvaise valeur, il y a trois conditions de résiliation possibles:
Quant au code réel, nous commençons dans le coin supérieur gauche. Le
(
transforme le zéro implicite au-dessus de la pile en un-1
, qui sera le total cumulé. On entre alors dans la boucle principale très serrée du programme+?-)"_,;+
,:Cela ne laisse que les cas où nous avons réduit le total cumulé à zéro à un moment donné. L'IP se déplace en bas à droite
,
et lit un autre caractère pour vérifier si nous avons atteint EOF. Sinon, la valeur sera positive et l'IP se tournera vers l'ouest vers le@
et le programme se terminera. Si nous avons atteint EOF, l'IP tourne vers l'est et imprime le-1
avec!
. L'IP se dirigera ensuite vers le coin inférieur gauche@
via un chemin légèrement étrange pour terminer le programme.la source
Python, 82 octets
Besoin de plus de cas de test.
la source
list
si c'est Python 2 au moins, et en réorganisant et en inversant la deuxième condition, vous pouvez l'obtenir à 70 octets:lambda l:all(l[x]<len(l)-x for x in range(len(l)))and len(l)==sum(l)+1
all
êtrex<len(l)-y for y,x in enumerate(l)
pour enregistrer encore 2 octets pour le porter à 68.Pyth, 13 octets
Nous commençons par calculer le remplissage actuel de l'arbre à tous les points de la représentation d'entrée. Cette partie de l'idée est en grande partie empruntée à Martin Ender, donc grâce à lui.
sM._tMQ
Une fois que nous avons cette liste, nous vérifions si le premier index contenant
-1
(x..._1
) est la longueur de l'entrée moins un (q...tl(Q)
).Vous ne croyez pas que cela fonctionne? Essayez-le vous-même!
la source