Цифровые сотовые автоматы

17

Напишите программу или функцию, которая принимает нечетное положительное целое число N и строку десятичных цифр ( 0123456789). Строка представляет собой одномерный клеточный автомат из десяти состояний . Каждая цифра занимает одну ячейку, и правило обновления от одного поколения к следующему состоит в том, что каждая ячейка становится цифрой, получающейся из суммы N ячеек, центрированных в ячейке, по модулю 10.

Первая и последняя ячейки обвиваются, как если бы они были соседями, поэтому в ячейках всегда может быть N клеток. Обратите внимание, что N может быть больше, чем длина строки, что означает, что она может быть обернута несколько раз, и некоторые цифры соответственно будут в сумме несколько раз.

Например, если N равно 7, а строка есть 038, чтобы визуализировать ячейки для суммирования, мы можем написать 038бесконечно повторяющиеся в обоих направлениях

...038038038038038...

тогда цифра, на которую 0преобразуется символ, является суммой 7 цифр, центрированных вокруг любой 0, по модулю 10:

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

Это то (0+3+8+0+3+8+0)%10, что есть 2.

Аналогично, цифры и 3и 8изменяются на (3+8+0+3+8+0+3)%10= 5и (8+0+3+8+0+3+8)%10= 0соответственно.

Таким образом, поколение после 038- это 250когда N равно 7.

Ваша программа или функция должна напечатать или вернуть цифровую строку самого следующего поколения входной цифровой строки. т.е. примените правило обновления один раз к каждой ячейке и выведите результат. Самый короткий код в байтах побеждает.

Тестовые случаи

[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
Кальвин Хобби
источник
@ LegionMammal978 Позволяет сохранить его как строку.
Увлечения Кэлвина
@ LegionMammal978 Нет. Признаюсь, я мог бы разрешить это изначально, но сейчас это несправедливо повлияет на существующие ответы, использующие строки.
Увлечения Кэлвина
Что ж, спасибо, что почти удвоил размер моего ответа ...
LegionMammal978

Ответы:

10

CJam, 21 байт

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

Проверьте это здесь.

объяснение

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.
Мартин Эндер
источник
5

Mathematica, 85 байт

""<>ToString/@CellularAutomaton[{Tr@#~Mod~10&,{},#/2-1/2},FromDigits/@Characters@#2]&
LegionMammal978
источник
Вы можете использовать .5вместо 1/2?
mbomb007
@ mbomb007 Нет, это должно быть целое число.
LegionMammal978
4

Python 3, 114 92 86 80 байт

Удалил 6 байтов благодаря Sp3000 и еще 6 байтов благодаря 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)

Определяет именованную функцию, aкоторая принимает Nи в Dкачестве параметров N и цифровую строку, определенную в задании.

объяснение

В Python 3 andмежду двумя строками будет последняя. Следовательно, D[i:]and ...короткое замыкание после того, как все центральные позиции будут итерированы, D[i:]будет пустой строкой и, следовательно, ложным. (D*N)[(i-N//2)%len(D):][:N]дублирует строку цифр несколько раз, а затем разрезает ее в нужных местах, чтобы получить подстроку с правильной цифрой в качестве центра. Вспомним на мгновение, что сумма цифр числа основания 10 по модулю 9 такая же, как и у самого числа по модулю 9. str(int(...,10)%10)обрабатывает результирующую строку чисел так, как если бы она была основанием 11 и получает остаток по модулю 10, затем преобразует обратно в строка. Наконец, a(N,D,i+1)переходит к следующей центральной позиции. Из-за того +, что после завершения рекурсии все полученные цифры объединяются и возвращаются.

Эльендия Старман
источник
3

Haskell, 92 байта

Преобразование строк действительно дорого в Хаскеле ...

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

Это определяет инфиксную функцию !, используемую следующим образом:

> "1234"!3
"7698"

объяснение

Справа мы имеем [div(1-n)2`mod`length x..], что только бесконечный список целых чисел , начиная с по (1-n)/2модулю length(x)(мы берем модуль, так как мы хотим , чтобы первый элемент был неотрицательным). Они соответствуют стартовым индексам окрестностей CA. Мы застегиваем его, xчтобы получить список правильной длины.

Функция <$>является инфиксной версией map, а ее левый аргумент является композицией функции, читаемой справа налево. Таким образом, для каждого целого числа в приведенном выше списке (извлекается с помощью fst) мы отбрасываем столько символов из cycle x(которое является конкатенацией бесконечно возможного количества копий x), берем nсимволы из остатка, преобразуем их в строки, а затем целые числа с read.pure, берем их сумму, преобразовать это в строку с showи взять последний символ того, что соответствует оставшемуся моду 10.

Zgarb
источник
2

NARS2000 APL, 37 символов (72 байта)

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

Объяснение:

  ⎕←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
источник
Разве APL не один байт на символ, так как кодировка не UTF-8? APL использует кодовую страницу APL .
mbomb007
Насколько мне известно, @ mbomb007 NARS2000 не поддерживает кодовую страницу APL, а ..примитив нестандартен и, следовательно, не "переносим".
Оберон
Может быть, короче использовать Dyalog APL?
mbomb007
1

Октава, 64 байта

@(s,n)["" mod(sum(bsxfun(@shift,s'-48,(1:n)-ceil(n/2))'),10)+48]
alephalpha
источник
1

J, 41 байт

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

Получилось дольше, чем я ожидал. Должно быть пригодным для игры в гольф.

Мы генерируем матрицу с элементами в строке, показывающими позиции, значения которых должны быть добавлены (мод 10), чтобы получить сумму за позицию.

Использование:

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

Попробуйте это онлайн здесь.

randomra
источник