Dans ce défi, votre tâche consiste à construire un graphe non orienté à partir d'une séquence de directives. Il existe une directive pour chaque entier non négatif, et chacune transforme un graphique donné en un nouveau.
- Directive
0
: ajoutez un nouveau nœud déconnecté. - Directive
1
: ajoutez un nouveau nœud et connectez-le à chaque nœud existant. - Directive
m > 1
: Supprimez tous les nœuds dont le degré (nombre de voisins) est divisible parm
. Notez que cela0
est divisible par tousm
, donc les nœuds déconnectés sont toujours supprimés.
Les directives sont appliquées une par une, de gauche à droite, en commençant par le graphique vide. Par exemple, la séquence [0,1,0,1,0,1,3]
est traitée comme suit, expliquée à l'aide d'un superbe art ASCII. Nous commençons avec le graphique vide et ajoutons un seul sommet comme indiqué par 0
:
a
Ensuite, ajoutez un autre sommet et connectez-le au premier, comme indiqué par 1
:
a--b
Nous ajoutons un autre sommet déconnecté puis un sommet connecté, comme indiqué par 0
et 1
:
a--b c
\ \ /
`--d
Nous répétons cette fois encore, comme dirigé par 0
et 1
:
,--f--e
/ /|\
a--b | c
\ \|/
`--d
Enfin, nous supprimons les sommets de degré 3 a
et b
, comme indiqué par 3
:
f--e
|\
| c
|/
d
Il s'agit du graphique défini par la séquence [0,1,0,1,0,1,3]
.
Contribution
Une liste d'entiers non négatifs, représentant une séquence de directives.
Production
Le nombre de nœuds dans le graphique défini par la séquence.
Cas de test
[] -> 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
Règles détaillées
Vous pouvez écrire une fonction ou un programme complet. Le nombre d'octets le plus court gagne. Les failles standard ne sont pas autorisées. Veuillez expliquer votre algorithme dans votre réponse.
Cela fait une semaine, j'ai donc accepté la réponse la plus courte. Si une version encore plus courte arrive plus tard, je mettrai à jour mon choix. Une mention honorable va à la réponse de Peter Taylor , sur laquelle plusieurs autres étaient basés, y compris le gagnant.
la source
Réponses:
Pyth ,
3731Cette solution utilise une fonction de réduction (
u
) pour créer une liste, où chaque entrée correspond à un nœud restant dans la liste, et la valeur de l'entrée correspondant à si le nœud a été initialement ajouté en vertu de la directive 0 ou 1.G
est la variable d'accumulateur dans la fonction de réduction et contient la liste susmentionnée. Il est initialisé à la liste vide,Y
.H
prend la valeur de chaque membre deQ
, l'entrée, un par un. Le résultat de l'expression est affecté àG
chaque fois, l'entrée suivante deQ
est affectée àH
et l'expression est réexécutée.Pour une mise à jour
G
correcte, il existe deux possibilités, une pour la directive 0 ou 1 et une pour les autres directives. Ces cas se distinguent avec le ternaire? ... <H2 ...
Si
H
est 0 ou 1, alors tout ce que nous devons faire est appendH
àG
.+GH
accomplit cela.Sinon, la première chose qui est nécessaire est de déterminer, pour chaque nœud du graphique, combien de voisins il a. Cela se fait en deux étapes:
Tout d'abord,
s>GT
compte le nombre de nœuds au niveau ou après le nœud d'entrée qui sont 1s. Ceux-ci sont tous connectés au nœud d'entrée, sauf que nous comptons plus que 1 si le nœud d'entrée est un 1.Deuxièmement, nous avons besoin du nombre de nœuds avant le nœud d'entrée qui lui sont connectés. Il s'agit de 0 si le nœud d'entrée est un 0, et l'indice du nœud d'entrée,,
T
si le nœud d'entrée est un 1. Cette valeur serait donnée par*@GTT
. Cependant, il reste le dépassement de la première section qui doit être corrigé. Ainsi, nous calculons à la*@GTtT
place, qui est 1 de moins si le nœud d'entrée est un 1. Ces valeurs sont additionnées, pour donner le nombre de nœuds connectés au nœud d'entrée.% ... H
donnera 0 est ce nombre est divisible parH
, et doit donc être supprimé, et ne donnera pas 0 sinon.f ... UG
donnera donc les indices de l'entrée qui ne doivent pas être supprimés, carf
est un filtre, et 0 est faux.m@Gd
convertit ces indices en 0 et 1 des nœuds correspondants.Enfin, une fois que la liste résultante des nœuds étiquetés 0 et 1 est trouvée, sa longueur est calculée (
l
) et imprimée (implicite).Idée large grâce à @PeterTaylor.
la source
GolfScript (53 octets)
Démo en ligne
Je n'ai pas encore joué au golf, mais j'ai découvert qu'il n'est pas très facile d'éliminer le
H
etT
variables donc cela pourrait être un minimum local.Prend entrée sur stdin au format
[0 1 2 3]
. Laisse la sortie sur la sortie standard.Non golfé:
la source
CJam,
129 75 73 68 61 4642 octetsSolution basée sur l'algorithme de Peter:
Expansion du code à suivre.
Solution précédente (61 octets):
Prend l'entrée de STDIN comme:
La sortie est le nombre sur STDOUT:
Algorithme :
U
qui stocke l'ID du nœud à ajouter.0
, ajoutez[U]
à une liste de liste1
, ajoutezU
à chaque liste dans la liste de liste et ajoutez une autre liste composée du premier élément de chacune de la liste de liste etU
length - 1
divisible parm
et je continue de noter le premier élément de ces listes. Après le filtrage, je supprime tous les identifiants supprimés de la liste restante des identifiants.Expansion du code :
Essayez-le ici
la source
Pyth,
888075 caractèresJ'ai fini. Peut-être que quelqu'un d'autre a des conseils sur le golf.
Y
est la liste d'adjacence du graphe. Pour des raisons de golf, je garde également un nœud dans cette liste, même après la suppression du nœud (sinon je devrais mettre à jour tous les index). Chaque nœud a lui-même comme voisin. La listeJ
conserve la trace des nœuds supprimés.Je montre les changements de la liste d'adjacence sur l'exemple d'entrée
[0,1,0,1,0,1,3]
:L'algorithme est alors assez simple: itérer sur toutes les entrées, si entrée == 0: ajouter un nouveau nœud avec lui-même comme voisin, si entrée == 1: ajouter un nouveau nœud avec tous les nœuds comme voisins (également les supprimés) et ajouter ce nœud à la liste d'adjacence de tous les nœuds, si entrée> 1: déterminez les nœuds avec # voisin-1% entrée == 0 et ajoutez-les pour
J
, dans chaque cas, mettre à jour les voisins de chaque nœud en utilisantJ
. À la fin, imprimez la longueur deY
moins la longueur de (l'ensemble de)J
.Usage
Appelez simplement le script et donnez comme entrée
[0,1,0,1,0,1,3]
ou un autre cas de test.la source
APL,
716555 caractères{⍬≡⍺:≢⍵⋄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,⍵}
Le graphique est représenté comme une matrice de contiguïté booléenne. Des lignes / colonnes sont ajoutées et supprimées si nécessaire.
la source
Python 2, 296
Chaque nœud reçoit un identifiant unique et les identifiants voisins de chaque nœud sont enregistrés. Lorsque la directive vaut 0, une liste de voisins vide est ajoutée pour le nouveau nœud. Lorsque la directive est 1, les identifiants de tous les nœuds existants deviennent la liste de voisins du nouveau nœud et toutes les autres listes de voisins sont mises à jour pour inclure le nouvel identifiant de nœud. Pour m> 1, les nœuds dont les listes de voisins sont multiples de m sont supprimés de la liste des nœuds et de toutes les listes de voisins. Merci à @Optimizer d'avoir attrapé un bogue dans une version antérieure.
la source
NetLogo, 160
La mise en œuvre est simple, lisant chaque symbole et effectuant l'action appropriée.
Vous pouvez exécuter à partir de la ligne de commande en tant que
f[0 0 1 1 0 0 1 1 2 5 7 0 1]
.la source
Ruby
159157( démo )Ceci définit une fonction appelée à l'
G
aide de la syntaxe stabby-lambda. UtilisationG[[0, 1]]
pour l'appeler avec les commandes0
et1
.L'implémentation est assez simple: il existe une
Node
structure (appeléeN
ci-dessus) qui contient des références à tous les nœuds liés via lal
propriété.G
crée des nœuds au besoin et manipule leurs liens. Une version lisible est disponible ici .la source
CJam,
9997 octetsIl y a encore beaucoup à jouer dans ce domaine. L'algorithme est basé sur le suivi de la matrice d'adjacence, mais représenter la matrice vide sans avoir à la traiter spécialement me donne des maux de tête.
Testez-le ici.
L'entrée est un tableau de style CJam:
Vous pouvez utiliser ce faisceau de tests pour exécuter tous les tests:
la source
Python 2, 174
Cela peut probablement encore être joué beaucoup.
J'ai utilisé un dictionnaire
g
pour représenter le graphique. Les nœuds sont étiquetés par des nombres et ils sont mappés à l'ensemble de nœuds adjacents. Cela signifie que chaque mise à jour d'un front doit être exécutée sur ses deux points de terminaison.De nouveaux indices de nœuds sont créés en comptant
n
. Chaque fois, je crée un nouveau nœud viden
. Pour le commandement0
, il reste juste. Pour la commande1
, il est connecté à chaque autre nœud viag[i]^={n};g[n]^={i}
; utiliser xor fait en sorte que le nœud ne soit pas connecté à lui-même. Pour les commandes> 1, il est immédiatement supprimé.Le filtrage des nœuds dont le degré est multiple se fait en trouvant d'abord les nœuds qui restent (
h
), puisand
intégrant avec la liste des nœuds et les voisins de chaque nœud.Enfin, le nombre d'entrées dans le dictionnaire graphique est la réponse.
la source
Mathematica, 223 octets
Wow, cela s'est avéré plus long que prévu.
Usage:
Voici les résultats des cas de test:
Moins golfé:
La façon dont cela fonctionne consiste à représenter le graphique comme une liste de "listes de voisins".
Pour la directive 0 , j'ajoute simplement une liste vide.
Pour la directive 1 , j'ajoute une liste de tous les nœuds précédents et j'ajoute le nouveau nœud à tous les nœuds précédents.
Pour une directive > 1 , j'ai supprimé les nœuds spécifiés et mis à jour le reste.
la source