Un tas de sable abélien , pour nos besoins, est une grille infinie avec des coordonnées entières, initialement vide de sable. Après chaque seconde, un grain de sable est placé à (0,0). Chaque fois qu’une cellule de la grille contient au moins 4 grains de sable, elle renverse simultanément un grain de sable sur chacun de ses quatre voisins. Les voisins de (x, y) sont (x-1, y), (x + 1, y), (x, y-1) et (x, y + 1).
Lorsqu'une cellule se renverse, ses voisins risquent de se renverser. Quelques faits:
- Cette cascade finira par s'arrêter.
- L'ordre dans lequel les cellules se répandent est sans importance; Le résultat sera le même.
Exemple
Après 3 secondes, la grille ressemble à
.....
.....
..3..
.....
.....
Après 4 secondes:
.....
..1..
.1.1.
..1..
.....
Après 15 secondes:
.....
..3..
.333.
..3..
.....
Et après 16 secondes:
..1..
.212.
11.11
.212.
..1..
Le défi
Dans le moins d'octets possible, écrivez une fonction qui prend un seul entier positif t et génère une image du tas de sable après t secondes.
Contribution
Un seul entier positif t , dans le format de votre choix.
Sortie
Une image du tas de sable après t secondes, en utilisant les caractères
. 1 2 3
Modifier: utilisez quatre caractères distincts que vous aimez ou dessinez une image. Si vous n'utilisez pas ".123" ou "0123", spécifiez dans votre réponse la signification des caractères.
Contrairement aux exemples, votre sortie doit contenir le nombre minimal de lignes et de colonnes nécessaires pour afficher la partie non nulle de la pile de sable.
C'est-à-dire que pour l'entrée 3, la sortie doit être
3
Pour 4, la sortie devrait être
.1.
1.1
.1.
Notation
Le score de golf standard s'applique.
Règles
Aucune fonction de langage ou bibliothèque qui sait déjà ce qu'est un tas de sable n'est autorisée.
Edit: la section de sortie a été modifiée, la restriction de jeu de caractères a été complètement levée. Utilisez quatre caractères ou couleurs distincts que vous aimez.
la source
0
? Quelle est la sortie alors?.
des cellules vides? Pouvons-nous avoir0
une cellule vide valide?Réponses:
R,
378343297291 octetsComme d'habitude, l'utilisateur fournit son entrée via
scan()
(j'ai déjà utilisé la variablet
, prenons-le à laz
place), la seconde ligne doit donc être lancée séparément, puis le reste:Les sorties d' un tableau qui contient les valeurs d'
a
aut
ième génération (0, 1, 2 ou 3).Cas de test:
Cela nous aide que cette chose soit symétrique à la fois verticalement et horizontalement, ce qui signifie que le point le plus à gauche a une hauteur de 4, cela signifie que les points le plus haut, le plus à droite et le plus bas sont également à 4.
Oh, et ai-je dit que vous pouvez faire de belles visualisations?
Après 1000 gouttes:
Après 50000 gouttes (≈4 secondes):
Après 333333 gouttes (15 minutes):
Vous pouvez aussi le dessiner!
Cette opération a pris 4 secondes pour 10000 itérations mais ralentit considérablement pour les baies plus grandes (par exemple quelques minutes pour 100000 itérations). C’est pourquoi il est si lent (j’ai estimé le taux de croissance comme dans et j’ai obtenu τ (i) ≈ 689 · i ^ 1,08, de sorte que le temps moyen par grain supplémentaire jusqu’à ce que tout le tas de sable s’installe après l’
i
étape est légèrement supérieur à un) , et le temps total en fonction du nombre de grains augmente un peu plus lentement que quadratiquement (T (i) 0,028 * i ^ 1,74):Et maintenant, avec une explication complète:
C’est la première fois de ma vie que la croissance d’objets (comme
a <- c(a, 1)
) fonctionne beaucoup plus vite que de pré-allouer une grande matrice vide pour les valeurs et de la remplir progressivement avec une tonne de zéros inutilisés.Mise à jour. Golfed 18 octets en éliminant
arr.ind
enwhich
raison de Billywob et en remplaçantrep(0,n)
avece=numeric;e(n)
dans 5 cas , en raison de JDL , et 17 plusieurs octets en raison de JDL .Mise à jour 2. Le tas de sable étant Abelian, il peut commencer par une pile de la hauteur souhaitée. J'ai donc supprimé la boucle redondante et amélioré considérablement la productivité!
la source
rep()
, étant donné que vous l’utilisez 6 fois. Deuxièmement, je ne pense pas que vous ayez besoin d’écrire l’arr.ind=T
option pour lawhich()
fonction. Il suffit d'utiliserwhich(...,T)
.n=numeric
et d’utiliser cela à la place, car iln(k)
ya moins de caractères quer(0,k)
. J'aime les images cependant.1%*%0
est moins de caractères quearray(0,c(1,1))
. De plus, le deuxième argumentu <- cbind
pouvant être simplement égal à 1,cbind
l'étendra par défaut à la longueur du premier argument.MATL ,
5553484342 octetsInspiré par la réponse de @ flawr .
Sortie graphique :
Essayez-le sur MATL Online! . Cela prend environ 10 secondes pour la saisie
30
. Vous devrez peut-être actualiser la page et appuyer à nouveau sur "Exécuter" si cela ne fonctionne pas.Voici un exemple de résultat pour l'entrée
100
:Sortie ASCII (43 octets) :
Essayez-le en ligne!
Explication
la source
1Y6
.~mod(spiral(3),2)
beaucoup plus malin :-)Matlab,
160 156148 octetsTout d'abord, une matrice trop grosse est créée, avec
n
le milieu quelque part. Ensuite, la cascade est calculée avec une convolution 2D très pratique. À la fin, l'excédent est coupé et le tout est converti en chaîne.Exemple de sortie pour
t=100
Comme toujours:
la source
v=any(z)
au lieu dev=find(sum(z))
(je l'utilise dans ma réponse). Aussi,2*~z
au lieu de(z<1)*2
n=500
... Cela faisaitn=400
plusieurs secondes que le traitement était en cours . Est-ce que je fais quelque chose de mal?n
ce programme génère une3*n x 3*n
matrice, il a donc besoin de stocker sur les9*n^2
chiffres. En outre, il est totalement inefficace, car nous avons également une longue itération totalement inutile allant de 1 à n. Mais là encore, c’est du code-golf , rendre un programme efficace est une tasse de thé différente.z=sparse(zeros(2*n+1))
et en modifiant la boucle for enwhile any(z(:)>3)
. Ensuite , vous pouvez peut - être aussi calculer le noyau de convolution une seule fois:kern = 1-mod(spiral(3),2)
.Python 2,
195 +1 +24 = 220217sortie pour n = 16
il y a BEAUCOUP de remplissage et d'itérations inutiles, en utilisant
n
comme limite supérieure "assez bonne", mais n = 200 toujours terminé en une seconde et n = 500 en environ 12 secondesnon-golfé
Le remplacement
return x
parimshow(x)
ajoute un caractère et génère une image interpolée laide, ce quiimshow(x,'gray',None,1,'nearest')
supprime l’interpolation floue, ce qui amène la sortie à la hauteur des spécifications.la source
ImportError: No module named convolve2d
. Changerimport scipy.signal.convolve2d as c
pourfrom scipy.signal import convolve2d as c
résoudre le problème. J'utilise scipy version 0.16.1, ai-je besoin d'une version plus ancienne ou plus récente? Ou le problème est-il autre chose?Perl,
157147 octetsInclut +1 pour
-p
Exécuter avec le décompte sur STDIN, imprime la carte en utilisant
0123
STDOUT:sandpile.pl
:la source
Python
32,418385362342330 octetsEdit: sauvegardé 6 octets grâce à @ Qwerp-Derp
Tout le mérite de @ Andreï Kostyrka, car il s'agit d'une traduction directe de son code R en Python.
la source
a,x,r
dans les arguments de la fonction.JavaScript,
418416406400393 octetsCrée une fonction anonyme qui affiche le résultat sur la console.
la source
Nim, 294 caractères
Compiler et exécuter:
Remarques:
x
est calculé comme le nombre de colonnes zéro au début de la ligne du milieu.x
lignes et les colonnes de chaque extrémité.Performance
la source
Scala, 274 octets
Usage:
scala sandpile.scala <iterations>
Je ne pense pas qu'il y ait beaucoup à expliquer à propos de celui-ci. Fondamentalement, il ajoute juste un grain de sable au centre. Ensuite, vérifie si elle est plus grande que 4, si c'est le cas, cela va déborder et vérifier que tous les voisins plus grands que 4, débordent, etc. C'est assez rapide.
Performance:
la source
J, 76 octets
Je définis un verbe
p
qui met une bordure de zéros autour de l’entrée. Le verbe principal prend un tableau en entrée. Il vérifie ensuite la première ligne pour tout tas de sable contenant 4 grains ou plus. Si tel est le cas, il génère le même tableau, à l'exception du remplissagep
, et sinon, il effectue une convolution 2D pour simuler la chute des grains. Le verbe principal est répété jusqu'à la convergence en utilisant l'opérateur électrique^:_
.Usage
Il faut environ 46 secondes pour calculer le résultat pour n = 50000. Le résultat peut être affiché à l'aide de l'
viewmat
addon avec un jeu de couleurs monochrome.la source
C 229 (avec beaucoup d'avertissements)
la source
APL (Dyalog Unicode) , SBCS de 51 octets
Essayez-le en ligne!
la source
PHP, 213 octets
crée récursivement la pile en se
$p
souvenant de sa taille$m
; puis imprime avec des boucles imbriquées.Courez avec
-r
.la source