Automates cellulaires numériques

17

Écrivez un programme ou une fonction qui accepte un entier positif impair N et une chaîne de chiffres décimaux ( 0123456789). La chaîne représente un automate cellulaire unidimensionnel à dix états . Chaque chiffre occupe une cellule et la règle de mise à jour d'une génération à la suivante est que chaque cellule devient le chiffre résultant de la somme des N cellules centrées sur la cellule, modulo 10.

La première et la dernière cellule s'enroulent comme si elles étaient voisines, de sorte que les cellules peuvent toujours avoir N cellules centrées sur elles. Notez que N peut être plus grand que la longueur de la chaîne, ce qui signifie qu'il peut s'articuler plusieurs fois et que certains chiffres seront donc plusieurs fois dans la somme.

Par exemple, si N est 7 et la chaîne est 038, pour visualiser les cellules à sommer, nous pouvons écrire en 038répétant infiniment dans les deux directions

...038038038038038...

alors le chiffre dans lequel le 0va changer est la somme des 7 chiffres centrés autour de tout 0, modulo 10:

...038038038038038...
      ^_____^
         |
    sum all these

C'est (0+3+8+0+3+8+0)%10, ce qui est 2.

De la même manière, les chiffres 3et et se 8transforment en sont définis respectivement par (3+8+0+3+8+0+3)%10= 5et (8+0+3+8+0+3+8)%10= 0.

Ainsi, la génération suivante 038est 250lorsque N est 7.

Votre programme ou fonction doit imprimer ou renvoyer la chaîne de chiffres de la toute prochaine génération de la chaîne de chiffres d'entrée. c'est-à-dire appliquer la règle de mise à jour une fois à chaque cellule et donner la sortie. Le code le plus court en octets gagne.

Cas de test

[digit string] -> [N = 1], [N = 3], [N = 5], [N = 7], [N = 9], [N = 43]
0 -> 0, 0, 0, 0, 0, 0
1 -> 1, 3, 5, 7, 9, 3
2 -> 2, 6, 0, 4, 8, 6
3 -> 3, 9, 5, 1, 7, 9
4 -> 4, 2, 0, 8, 6, 2
5 -> 5, 5, 5, 5, 5, 5
6 -> 6, 8, 0, 2, 4, 8
7 -> 7, 1, 5, 9, 3, 1
8 -> 8, 4, 0, 6, 2, 4
9 -> 9, 7, 5, 3, 1, 7
00 -> 00, 00, 00, 00, 00, 00
07 -> 07, 47, 41, 81, 85, 47
10 -> 10, 12, 32, 34, 54, 12
11 -> 11, 33, 55, 77, 99, 33
12 -> 12, 54, 78, 10, 34, 54
34 -> 34, 10, 78, 54, 12, 10
66 -> 66, 88, 00, 22, 44, 88
80 -> 80, 86, 46, 42, 02, 86
038 -> 038, 111, 294, 250, 333, 472
101 -> 101, 222, 343, 545, 666, 989
987 -> 987, 444, 901, 765, 222, 543
1234 -> 1234, 7698, 3412, 9876, 1234, 7698
26697 -> 26697, 54128, 00000, 56982, 84413, 54128
001002 -> 001002, 211122, 331332, 335334, 455544, 113112
129577020 -> 129577020, 326194923, 474081605, 961120291, 333333333, 183342413
6023845292173530 -> 6023845292173530, 6853571632015189, 1197228291289874, 9238433109901549, 0110956118726779, 1982123699138828
Loisirs de Calvin
la source
@ LegionMammal978 Permet de le conserver sous forme de chaîne.
Calvin's Hobbies
@ LegionMammal978 Non. J'avoue que j'aurais pu l'autoriser à l'origine mais le faire maintenant affecterait injustement les réponses existantes qui utilisent des chaînes.
Calvin's Hobbies
Eh bien, merci d'avoir presque doublé la taille de ma réponse ...
LegionMammal978

Réponses:

10

CJam, 21 octets

l~_,\2/f-l:~fm>:.+Af%

Testez-le ici.

Explication

l~   e# Read and evaluate N.
_,   e# Duplicate and turn into range [0 1 ... N-1]
\2/  e# Swap with other copy and (integer) divide by 2.
f-   e# Subtract this from each element in the range to get
     e# [-(N-1)/2 ... -1 0 1 ... (N-1)/2]
l:~  e# Read string and evaluate each digit separately.
fm>  e# Make one copy of the result for each element i in the range, shifting the array
     e# i cells to the right, cyclically.
:.+  e# Sum the columns of the resulting matrix.
Af%  e# Take each of those sums modulo 10.
Martin Ender
la source
5

Mathematica, 85 octets

""<>ToString/@CellularAutomaton[{Tr@#~Mod~10&,{},#/2-1/2},FromDigits/@Characters@#2]&
LegionMammal978
la source
Pouvez-vous utiliser à la .5place de 1/2?
mbomb007
@ mbomb007 Non, il doit s'agir d'un entier.
LegionMammal978
4

Python 3, 114 92 86 80 octets

A pris 6 octets grâce à Sp3000 et encore 6 octets grâce à xnor !

a=lambda N,D,i=0:D[i:]and str(int((D*N)[(i-N//2)%len(D):][:N],11)%10)+a(N,D,i+1)

Définit une fonction nommée aqui prend Net Dcomme paramètres, la chaîne N et chiffres définie dans le défi.

Explication

En Python 3, andentre deux chaînes finiront par être la dernière. Par conséquent, les D[i:]and ...courts-circuits une fois que toutes les positions centrales ont été itérées, ce D[i:]sera une chaîne vide et donc falsifiée. (D*N)[(i-N//2)%len(D):][:N]duplique la chaîne de chiffres plusieurs fois, puis la tranche aux bons endroits pour donner la sous-chaîne qui a le bon chiffre comme centre. Rappelons un instant que la somme des chiffres d'un nombre de base 10 modulo 9 est la même que le nombre lui-même modulo 9. str(int(...,10)%10)traite la chaîne de nombres résultante comme si elle était en base 11 et obtient le reste modulo 10, puis reconvertit en chaîne. Enfin, a(N,D,i+1)passe à la position centrale suivante. En raison de la +, une fois la récursion effectuée, tous les chiffres résultants sont regroupés et renvoyés.

El'endia Starman
la source
3

Haskell, 92 octets

La conversion de chaînes est vraiment chère à Haskell ...

x!n=last.show.sum.map(read.pure).take n.(`drop`cycle x).fst<$>zip[div(1-n)2`mod`length x..]x

Ceci définit une fonction d'infixe !, utilisée comme suit:

> "1234"!3
"7698"

Explication

Sur la droite, nous avons [div(1-n)2`mod`length x..], qui est juste la liste infinie d'entiers à partir de (1-n)/2modulo length(x)(nous prenons le module, car nous voulons que le premier élément soit non négatif). Ceux-ci correspondent aux indices de départ des quartiers CA. Nous le fermons avec xjuste pour obtenir une liste de la bonne longueur.

La fonction <$>est la version infixe de map, et son argument de gauche est une composition de fonction lue de droite à gauche. Ainsi, pour chaque entier de la liste ci-dessus (extrait avec fst), nous supprimons autant de caractères de cycle x(qui est la concaténation de copies infiniment de x), prenons les ncaractères du reste, les convertissons en chaînes, puis les entiers avec read.pure, prenons leur somme, convertissez-le en chaîne avec show, et prenez le dernier caractère de celui-ci, ce qui correspond au reste du mod 10.

Zgarb
la source
2

NARS2000 APL, 37 caractères (72 octets)

⎕←10⊥10∣+⌿⊃({⍵..-⍵}⌊⎕÷2)∘.⌽⊂49-⍨⎕AV⍳⍞

Explication:

  ⎕←10⊥10∣+⌿⊃({⍵..-⍵}⌊⎕÷2)∘.⌽⊂49-⍨⎕AV⍳⍞
⍝ ⎕←                                    output
⍝   10⊥                                 the base-10 digits in
⍝      10∣                              the modulo-10
⍝         +⌿                            column-wise sum of
⍝           ⊃                           the matrix version of
⍝                         ∘.⌽           the outer-product rotation of
⍝                            ⊂            the scalar version of
⍝                                 ⎕AV⍳    the index in the atomic vector of
⍝                                     ⍞   an input string
⍝                             49-⍨        minus 49 ('0' + 1)
⍝                                       by
⍝             {⍵..-⍵}                     the range ⍵ to -⍵, where ⍵ is
⍝                    ⌊                    the floor of
⍝                     ⎕                   an input integer
⍝                      ÷2                 divided by 2
Oberon
la source
N'est-ce pas APL un octet par caractère, puisque l'encodage n'est pas UTF-8? APL utilise la page de codes APL .
mbomb007
@ mbomb007 NARS2000 ne prend pas en charge la page de codes APL pour autant que je sache, et la ..primitive n'est pas standard et n'est donc pas "portable".
Oberon
Serait-il peut-être plus court d'utiliser Dyalog APL?
mbomb007
1

Octave, 64 octets

@(s,n)["" mod(sum(bsxfun(@shift,s'-48,(1:n)-ceil(n/2))'),10)+48]
alephalpha
la source
1

J, 41 octets

"."0@]{~(1":10|+/@:)#@]|-:@<:@[-~(+/&i.#)

S'est avéré plus long que prévu. Devrait être jouable au golf.

Nous générons une matrice avec des éléments dans une rangée montrant les positions dont les valeurs doivent être ajoutées (mod 10) pour obtenir la somme d'une position.

Usage:

   7 ("."0@]{~(1":10|+/@:)#@]|-:@<:@[-~(+/&i.#)) '038'
250

Essayez-le en ligne ici.

randomra
la source