Роздрукуйте різницю в послідовності Thue-Morse


10

Зверніть увагу, коли я кажу "заперечувати", я маю на увазі замінити всі нулі (тобто побітове заперечення)

Послідовність Чей-Морза йде як 01101001

Спосіб його створення:

Почніть з 0. Зніміть те, що залишилося, і додайте його до кінця.

Отже, візьміть 0. Негатуйте його та додайте це до кінця -01

Потім візьміть це і заперечуйте його і додайте це до кінця - 0110

І так далі.

Ще одна цікава властивість цього полягає в тому, що відстань між нулями створює "ірраціональну" і неповторювану струну.

Тому:

0110100110010110
|__|_||__||_|__|
 2  1 0 2 01 2          <------------Print this!

Чи можете ви написати програму, яка при введенні n видасть друковані перші n цифр рядка?

Це кодовий гольф, тому виграє найменша кількість байтів!


6
Не вимагає конкретної бази для виводу, схоже, лазівка. Сама послідовність Thue-Morse - це бажаний вихід, унарний та з роздільником 0.
Денніс

Відповіді:


2

Желе, 9 байт

;¬$‘¡TI’ḣ

Спробуйте в Інтернеті!

Як це працює

;¬$‘¡TI’ḣ  Main link. Argument: n

  $        Create a monadic chain that does the following to argument A (list).
 ¬         Negate all items of A.
;          Concatenate A with the result.
   ‘¡      Execute that chain n + 1 times, with initial argument n.
     T     Get all indices of truthy elements (n or 1).
      I    Compute the differences of successive, truthy indices.
       ’   Subtract 1 from each difference.
        ḣ  Keep the first n results.

4

Python 3 2, 104 92 88 84 байт

Це досить рудиментарне рішення, засноване на побудові потрійної послідовності Thue-Morse з нуля. Ця послідовність є ідентичною тій, що її запитують, хоча комусь іншому доведеться написати більш ретельне пояснення, чому це так. У будь-якому випадку ця послідовність є лише тривіальною модифікацією цієї, A036580 .

Редагувати: змінив цикл for на перегляд списку, змінив функцію на програму і змінив все на Python 2. Дякую Деннісу за допомогу в гольфі.

n=input()
s="2"
while len(s)<n:s="".join(`[1,20,210][int(i)]`for i in s)
print s[:n]

3

Джулія, 56 50 байт

n->(m=1;[m=[m;1-m]for _=0:n];diff(find(m))[1:n]-1)

Це анонімна функція, яка приймає ціле число і повертає цілий масив. Щоб викликати його, призначте його змінній.

Ми створюємо послідовність Thue-Morse, що змінюється бітом, починаючи з цілого числа m = 1, а потім додаємо 1-mдо разів mмасив n+1, де nвведення. Це генерує більше термінів, ніж нам потрібно. Потім ми знаходимо ті, що використовують find(m), отримуємо різницю між послідовними значеннями за допомогою diffта віднімаємо 1 по елементах. Прийняття перших nдоданків отриманого масиву дає нам те, що ми хочемо.

Збережено 6 байт і виправлено проблему завдяки Деннісу!


3

PowerShell, 102 байти

filter x($a){2*$a+([convert]::toString($a,2)-replace0).Length%2}
0..($args[0]-1)|%{(x($_+1))-(x $_)-1}

Трохи інший спосіб обчислення. PowerShell не має простого способу "отримати всі індекси в цьому масиві, де значення в цьому індексі дорівнює такому і тому ", тому нам потрібно бути трохи креативними.

Тут ми використовуємо A001969 , "числа з парним числом 1s у їх бінарному розширенні", що повністю збігається з індексами 0s у послідовності Thue-Morse. ;-)

filterОбчислює це число. Наприклад, x 4дав би 9. Потім ми просто переходимо 0до нашого введення $args[0], віднімаючи, 1тому що ми індексуємо нуль, і кожна ітерація циклу виводить різницю між наступним числом і поточним номером. Вихід додається на трубопровід і неявно виводиться новими рядками.

Приклад

PS C:\Tools\Scripts\golfing> .\print-the-difference-in-the-thue-morse.ps1 6
2
1
0
2
0
1

Відносини з A001969 - чудова знахідка!
Луїс Мендо

3

Хаскелл, 42 байти

l=2:(([[0..2],[0,2],[1]]!!)=<<l)
(`take`l)

Приклад використання: (`take`l) 7-> [2,1,0,2,0,1,2].

Це реалізація a036585_listвід A036585 зрушені вниз 0, 1і 2. Гольф: concat (map f l)є f =<< lі f 0=[0,1,2]; f 1=[0,2]; f 2=[1]є ([[0..2],[0,2],[1]]!!).

Примітка: lце нескінченна послідовність. Для впровадження функції take-first n-elements потрібно 10 байт або близько 25% .



3

MATL , 14 11 байт

Q:qB!Xs2\dQ

Спробуйте в Інтернеті!

Як вказував @TimmyD у своїй відповіді , бажану послідовність задають послідовні відмінності A001969 . Останнє, в свою чергу, може бути отримано у вигляді послідовності Thue-Morse плюс 2 * n . Тому бажана послідовність задається (послідовні відмінності послідовності Тю-Морза) плюс одна .

З іншого боку, послідовність Тю-Морза можна отримати як кількість одиниць у двійковому поданні n , починаючи з n = 0.

Q:q    % take input n implicitly and generate row vector [0,1,...,n]
B!     % 2D array where columns are the binary representations of those numbers
Xs     % sum of each column. Gives a row vector of n+1 elements
2\     % parity of each sum
d      % consecutive differences. Gives a row vector of n elements
Q      % increase by 1. Display implicitly

Чи можу я подати запит на дублювання (послідовні відмінності послідовності Тю-Морза) плюс 1 ?
CalculatorFeline

@CatsAreFluffy Ви абсолютно праві. Готово
Луїс Мендо


2

Пітон, 69 байт

t=lambda n:n and n%2^t(n/2)
lambda n:[1+t(i+1)-t(i)for i in range(n)]

iЙ член цієї послідовності 1+t(i+1)-t(i), де tфункція ТУЕ-Морса. Код реалізує його рекурсивно, що коротше, ніж

t=lambda n:bin(n).count('1')%2

1

Математика, 65 байт

SubstitutionSystem[{"0"->"012","1"->"02","2"->"1"},"0",#][[;;#]]&

Переможе мою іншу відповідь, але не обіграє надзвичайно пікантну версію для гольфу. Тепер зазвичай я вставляю свій код у лапки, а потім витягую його, тому що Mathematica любить додавати пробіли до вашого коду (які нічого не роблять), але він ніколи не псується з рядками, але це не працює для коду, який сам має лапки ...

Що б я не використовував, я просто використовую для цього магію. Вихід - це рядок.


Зараз у нас є 4 відповіді Mathematica: Моя оригінальна, невербальна (це 5, якщо вважається симболонна), екстра-гольф та моя магія.
CalculatorFeline

1

Математика, 58 байт

Differences[Nest[Join[#,1-#]&,{0},#]~Position~0][[;;#]]-1&

1
Звідки я можу знати, що ти не прийняв моє рішення та пограв у нього?
CalculatorFeline

@catsarefluffy Я адаптував вашу ідею, щоб генерувати послідовність (гольфуючи її за допомогою вирізання оператора інфіксації), але відчув, що метод, який використовується тут, перетворює це на призначений вихід, дуже відрізняється і більше підходить для нової відповіді, ніж запропонованого редагування.
Сіммонс

@catsarefluffy Я щойно бачив вашу редакцію. останнє, що я бачив, це було у первісному вигляді, коли я це робив. Я видалю цю відповідь, але вам доведеться просто повірити мені, що вона була незалежною :)
A Simmons

1;;#можна замінити просто ;;#.
LegionMammal978

Насправді я отримав вихідне перетворення з відповіді TimmyD. (Зокрема, перший абзац змусив мене згадати Position.)
КалькуляторFeline

1

Perl, 45 + 2 = 47 байт

$_=2;s/./(1,20,210)[$&]/ge until/.{@F}/;say$&

Потрібен прапор -pта -aпрапор:

$ perl -pa morse-seq.pl <<< 22                                                                            
2102012101202102012021

Порт @ Sherlock9 відповідь

Збережено 9 байт завдяки Тону


-aВаріант дає вам безкоштовну копію на вході, так$_=2;s/./(1,20,210)[$&]/ge until/.{@F}/;$_=$&
Ton Hospel

@TonHospel Це ідеально, не можу повірити, що я не думав про це :-) І я можу зберегти -pз -E: say$&в кінці, якщо припустити, що Perl> v5.18
andlrc

1

JavaScript (ES6), 73 67 байт

f=(n,s="2")=>s[n]?s.slice(0,n):f(n,s.replace(/./g,c=>[1,20,210][c]))

Порт відповіді @ Sherlock9.

редагувати: Збережено 6 байт завдяки @WashingtonGuedes.


Буде !s[n]працювати замість s.length<n? А може просто s[n]із ?:перевернутим?
знято

1

CJam (19 байт)

1ri){2b:^}%2ew::-f-

Демонстрація в Інтернеті

При цьому використовується підхід до збільшення послідовних відмінностей між елементами послідовності Тю-Морса.


Мій найкоротший підхід із використанням правил переписування - 21 байт:

ri_2a{{_*5*)3b~}%}@*<

(Попередження: повільно). Це кодує правила переписування

0  ->  1
1  ->  20
2  ->  210

як

x -> (5*x*x + 1) in base 3

0

Рубін, 57 байт

Порт відповіді Python xnor. Зміни, головним чином, полягають у потрійному висловлюванні tзамість того, що andвін 0був truthy в Ruby, а також використовує (1..n).mapта 1+t[i]-t[i-1]зберігає байти порівняно з імпортом розуміння списку безпосередньо.

t=->n{n<1?n:n%2^t[n/2]}
->n{(1..n).map{|i|1+t[i]-t[i-1]}}

0правда? Як це працює ??
CalculatorFeline

@CatsAreFluffy По моєму досвіду, погано
Sherlock9

0

Математика ( майже невербальна), 107 110 байт

({0}//.{n__/;+n<2#}:>{n,{n}/.x_:>(1-x)/._[x__]:>x}//.{a___,0,s:1...,0,b___}:>{a,+s/.(0->o),0,b}/.o->0)[[;;#]]&

Послідовність створюється багаторазовим застосуванням правила заміни. Інше правило перетворює його на потрібний вихід. Якщо достатньо людей зацікавить, я детально поясню.

не алфавітно-цифровий варіант

({$'-$'}//.{$__/;+$/#
<($'-$')!+($'-$')!}:>
{$,{$}/.$$_:>(($'-$')
!-$$)/.{$$__}:>$$}//.
{$___,$'-$',$$:($'-$'
)!...,$'-$',$$$___}:>
{$,+$$/.($'-$'->$$$$)
,$'-$',$$$}/.$$$$->$'
-$')[[;;#]]

як запропонував CatsAreFluffy.


Я думаю, що можна припустити, що люди достатньо зацікавлені в поясненні майже будь-якої відповіді. Якщо говорити лише про себе, я не підтримую подання без пояснень (якщо підхід очевидний).
Олексій А.

І якщо ви перетворите всі букви на послідовності $та заміните 0на x-x(де x - невикористана послідовність $) (і використовувати (x-x)!для 1 (ditto)), ми не будемо буквено-цифровими.
CalculatorFeline

Bytesave: Використовуйте {x__}замість_[x__]
CalculatorFeline

Я насправді впевнений, що Mathematica є повною Тюрінгом лише для символів або $[_]:=-/;(обох за допомогою емуляції лічильника)
CalculatorFeline
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.