Представьте себе «провод» с n
пробелами. Представьте далее, что в этом проводе есть «электроны». Эти электроны живут только одну единицу времени. Любые пространства в проводе, которые прилегают к одному электрону, становятся электроном. В терминологии Game of Life это так B1/S
.
Например, это провод длиной 10 с периодом 62.
правила
- Входные данные,
n
это одно положительное целое число. - Выходными данными должно быть одно целое число, обозначающее период провода длиной n.
- Начальное состояние - один электрон на одном конце провода.
- Период не обязательно включает начальное состояние. Некоторые длины никогда не возвращаются в исходное состояние, но все они периодические.
- Статический провод (т.е. без электронов) имеет период 1.
- Граничные условия не являются периодическими. То есть провод никоим образом не является тороидальным.
Контрольные примеры
Отдельное спасибо orlp за создание этого списка. (Я проверил это до n = 27.)
1 1
2 2
3 1
4 6
5 4
6 14
7 1
8 14
9 12
10 62
11 8
12 126
13 28
14 30
15 1
16 30
17 28
18 1022
19 24
20 126
21 124
22 4094
23 16
24 2046
25 252
26 1022
27 56
28 32766
29 60
30 62
31 1
32 62
33 60
34 8190
35 56
36 174762
37 2044
38 8190
39 48
40 2046
41 252
42 254
43 248
44 8190
45 8188
Вы можете увидеть тестовые случаи для n = 2 до 21 здесь с моим симулятором Game-of-Life-esque: Variations of Life .
РЕДАКТИРОВАТЬ: последовательность здесь была опубликована как A268754 !
code-golf
cellular-automata
El'ndia Starman
источник
источник
2^n-1
, потому что это число возможных ненулевых состояний «провода»The period does not necessarily include the starting state. Some lengths never return to the starting state, but all of them are periodic.
У вас есть пример?Ответы:
Python 2,
14814287 байтИспользует алгоритм обнаружения цикла Брента и, таким образом, на самом деле работает быстро.
Я также написал анимацию на Python (обе работы 2 и 3). Это должно
pyglet
бежать. Вы можете просмотреть анимацию, запустив:(Не стесняйтесь загружать суть и проверять код перед запуском.) Вы можете нажимать кнопки + и - для увеличения / уменьшения визуализируемого n .
И, наконец, для тех, кто заинтересован в дальнейшем изучении этой числовой последовательности, вот читаемая версия (она использовалась для генерации тестовых случаев выше):
источник
Mathematica, 127 байт
объяснение
Правило 18 :
Контрольные примеры
источник
Python 2, 68 байт
Обнаружение цикла может быть лучше, но итеративный шаг хорош.
Представляя массив в виде двоичного числа
k
, обновление можно выполнить, взяв XOR соk
смещением на одну влево/2
и одну вправо*2
, а затем обрезая доn
байтов как%2**n
.источник
Python
32,134121118 байтВ основном так же, как мой ответ Pyth , но несколько адаптировал его из-за отсутствия определенных встроенных функций в Python.
Безголовая версия:
источник
Pyth,
3936 байтИспользует функцию «накопленной фиксированной точки» для итерации до того, как конфигурация повторяется, и возвращает все промежуточные конфигурации в виде списка списков. Это работает, потому что правила являются детерминированными, а конфигурация следующего поколения является функцией текущей конфигурации. Это означает, что как только та же конфигурация появится снова, автоматы завершили цикл.
После достижения этого (последняя итерация цикла) она вызывает функцию следующего поколения в последний раз в последнем элементе списка «истории», чтобы получить следующую конфигурацию (которая является начальной конфигурацией цикла), и найти свой указатель в истории. Теперь период - это просто длина (1 + индекс окончания цикла) минус индекс начала цикла.
В питоническом псевдокоде:
Набор тестов занимает слишком много времени, чтобы сервер убил его, поэтому вам нужно будет использовать обычную программу и протестировать ее одну за другой, или установить Pyth (если вы этого не сделали) и использовать скрипт для его тестирования.
источник
Желе,
191817 байтЭтот код вычисляет первые 2 n состояния, поэтому он не особенно быстрый и не эффективен для памяти ...
Попробуйте онлайн! или проверьте первые 16 тестовых случаев .
Альтернативная версия, 13 байт (не конкурирует)
Версии Jelly, перенесшие эту проблему, имеют встроенное обнаружение петель, что делает решение более коротким и эффективным.
Это легко обрабатывает последний контрольный пример. Попробуйте онлайн!
Как это устроено
Обратите внимание, что вспомогательная ссылка применяется к 2 n в первой итерации, которая не кодирует допустимое состояние. Однако ((2 n ÷ 2) ^ (2 n × 2))% 2 n = (2 n - 1 + 2 n + 1 )% 2 n = 2 n - 1 , что является одним из возможных начальных состояний.
Поскольку мы выполняем цикл 2 n + 1 раз, мы гарантированно сталкиваемся с состоянием дважды, что делает обнаружение цикла успешным.
источник
CJam,
4134312725 байтСпасибо Деннису за сохранение 3 байта. Заимствование идеи из его ответа желе спасло еще 4.
Проверьте это здесь.
объяснение
Я представляю провод просто как целое число (чьи биты указывают позиции электронов) вместо того, чтобы использовать фактический список битов. Состояние обновляется с помощью довольно простых побитовых вычислений.
Чтобы найти период, мы собираем все промежуточные результаты в стеке, запускаем симуляцию для 2 n-1 +1 шагов, а затем определяем период как количество элементов с момента последнего появления конечного состояния (плюс 1).
Вот разбивка кода:
источник
JavaScript (ES6) 99
104Контрольная работа
источник
Haskell, 170 байт
x!p
дает элемент с индексом p, если в границах, иначе 0.n
вычисляет следующий шаг.g i
даетi
шаг.c x
дает период, если начинается сx
.f
оборачивает все это вместе.(Примечание: отправлено с телефона, который имеет интерпретатор объятий, который не является полнофункциональным, поэтому может иметь опечатки.)
источник
MATL ,
38373635 байтПри этом используется цикл, который продолжает вычислять новые состояния, пока новое состояние не станет равным любому из предыдущих. Каждое состояние - это вектор нулей и единиц. Эти векторы хранятся в виде строк растущего двумерного массива.
Вычисление каждого нового состояния выполняется путем свертки текущего состояния с последовательностью
[1,0,1]
, сохранения только центральной части и установки0
любой записи, которая не является1
.РЕДАКТИРОВАТЬ (13 мая 2016 г.) Код в следующей ссылке был слегка изменен в соответствии с изменениями, внесенными в язык после написания этого ответа
Попробуйте онлайн!
источник
Perl 6, 81 байт
Немного расширился и расклеился
Немного объяснения:
[op]
сокращает список с помощью оп. Например[+] @list
будет сумма@list
R
это метаоперация, которая переворачивает аргументы, данные оператору Например1 R- 3
приведу в 2.источник
C ++, 211 байт
Golfed
С добавленным пробелом для удобства чтения
Хорошая практика для набора битов C ++; и хорошее образование, узнающее об алгоритме обнаружения цикла Брента (как используется @orlp)
источник
Pyth, 95 байт
Вы можете попробовать это здесь .
источник
Pyth, 29 байт
Использует алгоритм
a(n+1) = ((a(n) << 1)^(a(n) >> 1)) % (2 ** N)
.источник
Рубин, 72 байта
Анонимная функция.
источник