Un graphe *** ameoba **** est un type d' arbre dont les nœuds ont tous des valeurs de 0 à un entier non négatif N, et tout nœud particulier avec la valeur x <N se connecte à x + 1 nœuds distincts avec les valeurs x + 1.
Graphique Ameoba pour N = 3: (noté A 3 )
Notez que les 2 ne sont autorisés à partager aucun des 3; exactement trois 3 doivent "appartenir" à chacun des 2.
Défi
Votre tâche est de "développer" par induction ces graphiques ameoba dans une grille à 2 dimensions en minimisant goulûment la distance de Manhattan entre les nœuds:
- Cas de base: Un 0 est simplement le graphique
0
. - Étape inductive: un N + 1 est généré en plaçant de manière itérative les nouveaux nœuds à valeur N + 1 aussi près que possible des nœuds à valeurs N dans la structure A N existante . (Il ne peut être aussi proche que possible car les emplacements les plus proches peuvent déjà être remplis.)
Pour l'étape inductive, la procédure générale que vous devez suivre est la suivante:
for each existing node P with value N:
for each new N+1 valued node Q you need to connect to P: //this loops N+1 times
find the set of vacant spots that are minimally distant from P //by Manhattan distance
place Q in any of these vacant spots
(Une procédure différente avec une sortie impossible à distinguer est très bien.)
Exemple de croissance pour A 4 :
A0 is always the same:
0
For A1 I happen to put the 1 to the right of the 0 (it has to go on one of the 4 open sides):
01
For A2 I happen to put the two 2's above and to the right of the 1:
2
012
For A3 I find that one of the six 3's I must place cannot be directly next to a 2, so I put in one of the next closest places:
3
323
0123
33 <-- this 3 is distance two away from its 2
The process continues in A4. Note that I'm iterating over each 3 and placing four 4's next to it or as close as possible, then moving to the next 3 (the order of 3's does not matter):
444
443444
4323444
4012344
44334
4444
44
Always keep in mind that nodes cannot be "shared".
Programme
Le programme que vous écrivez doit prendre un nombre compris entre 0 et 8 (inclus) et en produire un graphique ameoba valide, en utilisant le schéma de croissance inductif expliqué ci-dessus.
Ce qui se passe au-delà de 8 n'a pas d'importance.
(A 8 contient 46234 nœuds qui le poussent. Tout ce qui dépasse A 8 serait trop loin. Merci à Martin Büttner de l'avoir remarqué.)
L'entrée doit provenir de stdin ou de la ligne de commande et la sortie doit aller vers stdout ou un fichier.
Exemples (pris directement d'en haut)
Input: 0
Output:
0
Input: 1
Output:
01
Input: 2
Output:
2
012
Input: 3
Output:
3
323
0123
33
Input: 4
Output:
444
443444
4323444
4012344
44334
4444
44
* Ces types de graphiques peuvent déjà avoir un nom. J'avoue que je viens de les inventer. ;)
Réponses:
Mathematica,
353288285275 octetsNon golfé:
Voici un exemple de sortie pour
n = 5
:L'entrée
8
prend environ 4,5 minutes.Pour une ventilation rapide de mon algorithme:
J'utilise deux tables de recherche,
f
etg
. La première est juste une carte clairsemée contenant les cellules non vides. Ce dernier est une liste contenant toutes les paires de coordonnées pour chaque valeur de cellule (je pense que je n'ai même pas besoin de garder une trace des anciennes ici). J'itère à travers les coordonnéesg
pour étendre chaque cellule de la dernière itération. Pour ce faire, j'itère sur les distances de Manhattan, créant tous les vecteurs possibles pour chaque distance et vérifiant si la cellule résultante est toujours vide (auquel cas je la remplis). Répétez jusqu'à ce que suffisamment de nouvelles cellules aient été créées.Lorsque j'ai terminé, je trouve les coordonnées minimale et maximale dans
g
et je crée une grille appropriée, qui est remplie en recherchant les cellulesf
. Le reste consiste simplement à tout joindre en une seule chaîne avec des sauts de ligne.la source
C -
309 305 301275 octetsMeh, trop longtemps ... si un seul pouvait taper
#D
ou quelque chose à la place#define
, alors C serait vraiment super. Bien sûr,-D
les drapeaux du compilateur sont possibles, mais cela me semble tricher, d'avoir des caractères autres que ceux du fichier source.Instructions de course:
Faites attention! La première touche sur laquelle vous appuyez après le démarrage du programme constitue l'entrée. Lors d'une entrée de caractère autre que «0» à «8», qui sait quelles choses non définies se produiront.
Version non golfée (mais qui pense déjà au futur golf):
Edit: J'ai réalisé que depuis que j'ai déplacé les déclarations en dehors de main (), les tableaux ne peuvent plus être alloués sur la pile, donc je suis libre d'utiliser la mémoire de manière profligée sans risque de débordement.
la source
Rubis - 296
Légèrement non golfé.
la source
APL (Dyalog) (121)
Caractéristiques de performance: c'est O (n!). Sur mon système, jusqu'à n = 5, c'est instantané; n = 6 prend une seconde, n = 7 prend une minute et n = 8 prend une heure.
Version non golfée
Tester:
Explication:
{
...}⎕
: lire une ligne du clavier, l'évaluer et transmettre le résultat à la fonction.0::0
: si l'autre code génère une erreur, renvoyez-en un simple0
. Cela est dû au fait que les calculs échouent lors de la tentative de calcul de la taille d'un graphique à 0 nœuds, ce qui se produit lorsque la sortie doit l'être0
. (La version précédente avait⍵=0:0
, (si l'entrée est0
retournée,0
sinon, faites le graphique), mais0::0
(essayez-la et retournez-la0
si elle échoue) est plus courte.)M←⌈4×.5*⍨3÷⍨+/!⍳⍵
: en supposant que la sortie est un cercle approximatif (cela fonctionne), additionnez les factorielles de1
à⍵
(= zone de sortie), divisez par 3 (assez proche de pi), prenez la racine carrée (donnant le rayon de sortie), multipliez par 4, et prenez le plafond. Cela donne deux fois le diamètre du cercle, de sorte que la sortie s'adapte à l'espace disponible. Conservez-le dansM
.V←,⍳⍴Z←' '⍴⍨2/M
: créer une matrice d'espaces M-par-M et la stockerZ
. Cela conservera la sortie. Stockez une liste des coordonnées de tous les éléments dansV
.Z[G;G←⌈M÷2]←'0'
: définir l'élément central deZ
à0
.Z⊢{
...}¨⍳⍵
: retourZ
, après avoir appliqué la fonction suivante aux nombres1
à⍵
:⍵∘{
...}V/,Z=⍕⍵-1
: pour chaque élémentZ
avec la valeur du nœud précédent:⍵∘{
...}⍺/⍺
: pour le nœud courant, N fois,⊃F[⍋+/¨|(F←V/⍨,Z=' ')-⊂⍺]
: obtenir l'espace libre le plus proche du nœud actuel,(
...⌷Z)←⍕⍵
: et définissez cet espaceZ
sur la valeur du nœud actuel.la source