Послідовність кривої дракона


23

Послідовність кривої дракона (або звичайна послідовність складання паперу) - це двійкова послідовність. a(n)задається запереченням біта, що залишився від найменш значущого 1 n. Наприклад, для обчислення a(2136)ми спочатку перетворюємо на двійкові:

100001011000

Ми знаходимо наш найменш вагомий біт

100001011000
        ^

Візьміть шматочок ліворуч

100001011000
       ^

І повернути своє заперечення

0

Завдання

Дано додатне ціле число як вхід, вихід a(n). (Ви можете виводити цілим чи булевим). Ви повинні прагнути зробити свій код якомога меншим, виміряним байтами.

Випробування

Ось перші 100 записів по порядку

1 1 0 1 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 1 1 0 0 0 1 1 0 0 1 0 0 1 1 1 0 1 1 0 0 1 1 1 0 0 1 0 0 0 1 1 0 1 1 0 0 0 1 1 0 0 1 0 0 1 1 1 0 1 1 0 0 1 1 1 0 0 1 0 0 1 1 1 0 1 1 0 0 0 1 1 0 0 1 0 0 0 1 1 0 1


9
Найменш значущий біт 100001011000- це 0. Ви маєте на увазі найменш значущий 1?
розкидання

Відповіді:


16

Математика 25 байт

1/2+JacobiSymbol[-1,#]/2&

Інші способи зробити це:

56 байт

(v:=1-IntegerDigits[#,2,i][[1]];For[i=1,v>0,i++];i++;v)&

58 байт

1-Nest[Join[#,{0},Reverse[1-#]]&,{0},Floor@Log[2,#]][[#]]&

3
Оце Так! Відповідь математики, але вона не побудована лише в. Майте нагороду!
KeyWeeUsr

2
Єдине, що може зробити цю відповідь ще кращою - це пояснення, чому і як це працює. : P
Мартін Ендер

2
@MartinEnder arxiv.org/pdf/1408.5770.pdf Дивіться зауваження після прикладу 13.
alephalpha

7

Python 3 , 22 21 байт

1 байт завдяки ETHproductions.

lambda n:n&2*(n&-n)<1

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

Побітова арифметика ftw.


2
"Ви можете виводити цілим чи булевим", так що я думаю, вам це не потрібно 0+(...)?
Мартін Ендер

Порядок операцій тут мене справді бентежить. Чи n&1можна вкласти в дужки? Або це 1+(n^~-n)<1може бути в дужках? Або це 1+(n^~-n)...
ETHproductions

о боже що. ось що я шукав: o приємно!
HyperNeutrino

&має найнижчий пріоритет, так це1+(n^~-n)
Leaky Nun

А, знайшов таблицю пріоритету. Тепер це має сенс: P
ETHproductions

6

Сітківка ,38 34 29 байт

\d+
$*
+`^(1+)\1$|1111
$1
^1$

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

Мартін та Лікі, по суті, придумали цю ідею, на ще 5 байт!

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


31 байт (чи варто я це розміщувати сам?)
Leaky Nun

Я знайшов спосіб уникнути повної бінарної конверсії і замість цього просто розділити коефіцієнти 2 і перевірити рівність з 1 (mod 4): tio.run/##K0otycxL/…
Мартін Ендер

@MartinEnder, по суті, мій алгоритм ... з 2 байтами
Leaky Nun

@LaakyNun О так, вони обоє однакові. Чудові розуми та речі ...;)
Мартін Ендер

Я відредагую це, але якщо хтось із вас захоче опублікувати його, я повернусь, як я, мабуть, сам про це не подумав би;)
FryAmTheEggman

6

Желе , 5 байт

&N&HṆ

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

Як це працює

&N&HṆ  Main link. Argument: n

 N     Negate; yield -n.
&      Bitwise AND; compute n&-n.
       This yields the highest power of 2 that divides n evenly.
   H   Halve; yield n/2.
  &    Bitwise AND; compute n&-n&n/2. This rounds n/2 down if n is odd.
    Ṇ  Take the logical NOT of the result.

4

Аліса , 8 байт

I2z1xnO@

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

Приймає введення як кодову точку символу Unicode і видає результат відповідно 0x00 або 0x01 байт.

Для перевірки, ось десяткова версія вводу / виводу в 12 байт, яка використовує абсолютно той самий алгоритм (тільки введення / виведення відрізняється):

/o
\i@/2z1xn

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

Якби Аліса була мовою для гри в гольф і не вимагала явного вводу / виводу та припинення програми, вона 2z1xnзапустила б лише 5 байт ( ), побивши і 05AB1E, і Jelly.

Пояснення

I    Read input.
2z   Drop all factors of 2 from the input, i.e. divide it by 2 as long
     as its even. This shifts the binary representation to the right
     until there are no more trailing zeros.
1x   Extract the second-least significant bit.
n    Negate it.
O    Output it.
@    Terminate the program.


3

Мудрий , 28 20 16 байт

::-~^~-&:[?>]~-^

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

Пояснення

Це порт відповіді Leaky Nun's Python. На жаль, це не працює над TIO, оскільки версія інтерпретатора TIO трохи застаріла.

Почнемо, зробивши 3 копії нашого вводу ::, потім згортаємо верхню копію на 1. Це переверне всі біти до першого 1. Потім ми скорійовуємо це іншою копією нашої інформації. Оскільки всі біти аж до першого 1 на нашому введенні були перевернуті, це призведе до того, що всі біти будуть 1 за результатом. Якщо потім додати його ~-до результату, ми отримаємо одинарне 1 в місці зліва від нашого найменш значущого 1. Ми ТА це з введенням, щоб отримати цей біт від вхідного даних. Тепер у нас буде 0iff, що біт був відключений, і потужність 2 iff, що біт був увімкнений, ми можемо змінити це на єдине 1або 0з :[?>]. Як тільки це буде зроблено, нам потрібно лише заперечувати шматочки, ~-^і ми закінчили.



3

Haskell , 45 43 39 байт

6 байт збережено завдяки німі

f x|d<-div x 2=[f d,mod(1+d)2]!!mod x 2

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


Ви можете використовувати divзамість quot.
німі

Ще краще: divMod:f x|(d,m)<-divMod x 2=[mod(1+d)2,f d]!!m
Ними

@nimi Я навіть не розумію, як це працює. Вам, мабуть, варто просто опублікувати його самостійно.
Пшеничний майстер

Це все той же алгоритм, але просто інший спосіб , щоб вибрати гілку (рекурсивний виклик е знову проти базового випадку), так що ні соромтеся редагувати його. |(d,m)<-divMod x 2Це шаблон охоронець для прив'язки dдо div x 2і mдо mod x 2. Ми використовуємо mдля індексації списку двох елементів [...,...]!!m. У разі m==0повернення mod(1+d)2і у випадку m==1 f d.
німі

1
Ой, вибачте, ви повинні перевернути елементи списку: [f d,mod(1+d)2]. Спробуйте в Інтернеті! .
німі

3

машинний код x86, 17 16 15 байт:

Припускає ABI, де параметри висуваються на стек і значення повернення знаходиться в ALрегістрі.

8B 44 24 04 0F BC C8 41 0F BB C8 0F 93 C0 C3

Це розбирається так:

_dragoncurve:
  00000000: 8B 44 24 04        mov         eax,dword ptr [esp+4]
  00000004: 0F BC C8           bsf         ecx,eax
  00000007: 41                 inc         ecx
  00000008: 0F BB C8           btc         eax,ecx
  0000000B: 0F 93 C0           setae       al
  0000000E: C3                 ret

1
@PeterTaylor Я вважаю розмір інструкції CPU в байтах для своєї відповіді; це досить поширена практика на PPCG для збирання відповідей.
Говінд Пармар

1
Я не міг сказати, наскільки це часто, але це, безумовно, неправильно
Пітер Тейлор

1
Це не просто педантично, але й безглуздо. Що стосується комп'ютера, то немає різниці між "машинним кодом" та "кодом складання". Різниця полягає лише в інтерпретації. Ми присвоюємо мнемоніки машинним байтовим кодом, щоб полегшити людське читання. Іншими словами, ми розкручуємо байти, щоб полегшити їх розуміння.
Коді Грей

3
Це не має значення, @ Петер. Код складання - це просто читаний людиною переклад машинного коду. Вони абсолютно однакові, лише у двох різних формах / уявленнях. Це не відрізняється від TI BASIC, де прийнято вважати лексеми замість байтів символів, оскільки система їх зберігає всередині них. Те саме було б і з мовою складання: мнемоніка інструкцій не зберігається як окремі символи, а представлена ​​у вигляді байтів еквівалентного машинного коду.
Коді Грей

2
Крім того, практично кажучи, чому б хто- небудь коли-небудь вступав у розширену мнемоніку мови збірки в змаганнях з кодом-гольфу, коли вони могли перевести їх на 100% еквівалентний машинний код, де запис гарантовано буде коротшим безкоштовно? Це одне лише робить відмінність між двома безглуздими, якщо не зовсім абсурдними.
Коді Грей

3

JavaScript (ES6), 17 14 байт

f=
n=>!(n&-n&n/2)
<input type=number min=0 oninput=o.textContent=f(this.value)><pre id=o>

Редагувати: збережено 3 байти, перенісши відповідь @ Денніса, як тільки я помітив, що булевий вихід прийнятний.


3

C (gcc) , 20 байт

f(n){n=!(n&-n&n/2);}

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


Це насправді не "працює"; ви покладаєтесь на химерність генератора коду для однієї конкретної версії компілятора, націленої на одну конкретну архітектуру, де проміжні обчислення робляться в тому ж реєстрі, який використовується для повернення значень. Увімкнення будь-якого типу оптимізації, зміна цільової архітектури або використання іншої версії GCC це порушить. Ви також можете просто сказати, що "сміття в моїй стеці містить правильний вихід, коли повний місяць 13 жовтня".
Коді Грей

Хоча все, що ви говорите, є правдивим і подібний код ніколи не використовується у виробничому коді, ми визначаємо мови за їх реалізацією для цілей коду golf. Без додаткових прапорів це працює у всіх останніх версіях gcc та tcc, і він повинен працювати лише в одній версії, щоб вважати його дійсним.
Денніс

"ми визначаємо мови за їх реалізацією для цілей коду гольфу" Зачекайте, що? Отже, кожен прапор компілятора та кожна версія GCC визначає іншу мову? Ви розумієте, що це божевільно, правда? Стандарт мови C - це те, що визначає мову.
Коді Грей

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

Ого. Це горіхи. Я маю на увазі, я міг би зрозуміти, якби ви говорили, що визначена реалізацією поведінка дозволена, але невизначена поведінка не визначається реалізацією. Це буквально невизначено. Програмі дозволяється робити випадкові речі кожен раз. І це поняття "стандартні прапори компіляції" - це те, що ви щойно вигадали. Мої стандартні прапори компіляції містять кілька, які порушують ваш код. І я навряд чи думаю, що оптимізатор є нестандартним. Ну, явно цей сайт не для мене.
Коді Грей

3

INTERCAL , 50 байт

DOWRITEIN.1DO.1<-!?1~.1'~#1DOREADOUT.1PLEASEGIVEUP

Одинакові оператори INTERCAL для цього цілком підходять, тому я вирішив написати своє перше повідомлення.

DO WRITE IN .1
DO .1 <- !?1~.1'~#1
DO READ OUT .1
PLEASE GIVE UP


2

Желе , 7 6 байт

1 байт завдяки Еріку Переможнику.

Bt0ṖṪṆ

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

Більш тривалі програми


Хм ... ну, ви можете просто зробити ṖṪṆ(як моя видалена відповідь) замість ṫ-ḄỊ.
Ерік Аутгольфер

1
Ще один для вашого 7-байтного списку:BUḌDḊḢ¬
steenbergh

2

,,, , 10 9 байт

::0-&2*&¬

Пояснення

Візьміть, наприклад, дані 3.

::0-&2*&1≥
               implicitly push command line argument       [3]
::             duplicate twice                             [3, 3, 3]
  0            push 0 on to the stack                      [3, 3, 3, 0]
   -           pop 0 and 3 and push 0 - 3                  [3, 3, -3]
    &          pop -3 and 3 and push -3 & 3 (bitwise AND)  [3, 1]
     2         push 2 on to the stack                      [3, 1, 2]
      *        pop 2 and 1 and push 2 * 1                  [3, 2]
       &       pop 2 and 3 and push 2 & 3                  [2]
        ¬      pop 2 and push ¬ 2 (logical NOT)            [0]
               implicit output                             []


2

Октава , 34 байти

@(x)~(k=[de2bi(x),0])(find(k,1)+1)

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

Пояснення:

@(x)                               % Anonymous function taking a decimal number as input
    ~....                          % Negate whatever comes next
     (   de2bi(x)   )              % Convert x to a binary array that's conveniently 
                                   % ordered with the least significant bits first
        [de2bi(x),0]               % Append a zero to the end, to avoid out of bound index
     (k=[de2bi(x),0])              % Store the vector as a variable 'k'
                     (find(k,1)    % Find the first '1' in k (the least significant 1-bit)
                               +1  % Add 1 to the index to get the next bit
     (k=[de2bi(x),0])(find(k,1)+1) % Use as index to the vector k to get the correct bit

Чому я ніколи не чув про de2bi ...: O
Санчіз

1

Подання:

Python 2 , 41 39 байт

x=input()
while~-x&1:x/=2
print 1-x/2%2

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

-2 байти завдяки FryAmTheEggman

Початкове рішення:

Python 2 , 43 байти

lambda x:1-int(bin(x)[bin(x).rfind('1')-1])

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


Отже, яке ваше подання?
Leaky Nun

@LeakyNun Перший, тому що він коротший; друге - моє первісне подання. Чи потрібно публікувати їх окремо?
HyperNeutrino

~-x&1працює на той час, натомість, я думаю.
FryAmTheEggman

(Я забуваю ім’я користувача); Я відхилив вашу редагування, оскільки редагування коду чужих гольфів не рекомендується в PPCG. Ви можете розміщувати пропозиції (btw, спасибі @FryAmTheEggman), але, будь ласка, не вносити зміни в гольф. Спасибі!
HyperNeutrino

@StewieGriffin Ага так, дякую. На жаль, я не можу пінг користувача, оскільки редагування було відхилено.
HyperNeutrino

1

MATL , 11 10 байт

t4*YF1)Z.~

Спробуйте в Інтернеті! Або подивіться перші 100 виходів .

Пояснення

t    % Implicit input. Duplicate
4*   % Multiply by 4. This ensures that the input is a multiple of 2, and
     % takes into account that bit positions are 1 based
YF   % Exponents of prime factorization
1)   % Get first exponent, which is that of factor 2
Z.   % Get bit of input at that (1-based) position
~    % Negate. Implicit display


1

Befunge-98 , 19 байт

&#;:2%\2/\#;_;@.!%2

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

&#                       Initial input: Read a number an skip the next command
  ;:2%\2/\#;_;           Main loop: (Direction: East)
   :2%                    Duplicate the current number and read the last bit
      \2/                 Swap the first two items on stack (last bit and number)
                          and divide the number by two => remove last bit
         \                swap last bit and number again
          #;_;            If the last bit is 0, keep going East and jump to the beginning of the loop
                          If the last bit is 1, turn West and jump to the beginning of the loop, but in a different direction.
&#;           @.!%2      End: (Direction: West)
&#                        Jump over the input, wrap around
                 %2       Take the number mod 2 => read the last bit
               .!         Negate the bit and print as a number
              @          Terminate

1

SCALA, 99 (78?) Символів, 99 (78?) Байт

if(i==0)print(1)else
print(if(('0'+i.toBinaryString).reverse.dropWhile(x=>x=='0')(1)=='1')0 else 1)

де iвхід.

Як бачите, я заощаджую 21 байт, якщо я не подбаю про нуль (як це робив автор у своєму тестовому випадку):

print(if(('0'+i.toBinaryString).reverse.dropWhile(x=>x=='0')(1)=='1')0 else 1)

Це мій перший кодогольф, тому я сподіваюся, що я зробив добре :)

Спробуйте в Інтернеті! Хоча обчислювати лол досить довго.


Ласкаво просимо на сайт!
DJMcMayhem


1

Java 8, 17 байт

n->(n&2*(n&-n))<1

Прямий порт відповіді LeakyNun на Python 3 . Я недостатньо знайомий з побітними операціями та пріоритетом оператора, щоб побачити коротше рішення; можливо, є спосіб уникнути зайвої парентези?


0

Japt , 10 8 9 байт

!+¢g¢a1 É

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

Пояснення

!+¢   g    a1 É
!+Us2 gUs2 a1 -1 # Implicit input (U) as number
!+               # Return the boolean NOT of
      g          #   the character at index
       Us2       #     the input converted to binary
           a1    #     the index of its last 1
              -1 #     minus 1
      g          #   in string
  Us2            #     the input converted to binary

Це повертається falseза все, тому що символ (0 або 1) - це завжди рядок.
Кудлатий

На жаль, я повинен був помітити, що ... Виправлено зараз
Лука

Схоже, зараз це не вдається1 .
Кудлатий

0

JavaScript (ES6), 53 34 байти

a=>eval("for(;~a&1;a/=2);~a>>1&1")

42 байти:a=>!+(a=a.toString(2))[a.lastIndexOf(1)-1]
Шаггі

Я вже знайшов коротше (математичне) рішення ...
Лука

Приємно :) Майте на увазі, якщо я опублікую цей 42 байт?
Кудлатий

@Shaggy, зовсім не так
Лука



0

Чіп , 93 байти

HZABCDEFG,t
 ))))))))^~S
H\\\\\\\/v~a
G\\\\\\/v'
F\\\\\/v'
E\\\\/v'
D\\\/v'
C\\/v'
B\/v'
A/-'

Вводить як мало ендіакальних байтів. (У TIO є трохи пітона, який робить це для вас). Дає вихід або як 0x0або 0x1. (TIO використовує xxd для перевірки значення).

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

Як це зробити?

Чіп дивиться на вхід один байт за часом, тому обробка багатобайтового вводу додає деяку частину маси, але не настільки, наскільки я боявся.

Давайте перейдемо до цього:

HZABCDEFG

Це - HZвисокий біт попереднього байта (якщо такий був), і A- Gсім нижніх бітів поточного байта. Вони використовуються для пошуку найнижчого встановленого біта числа.

        ,t
))))))))^~S

Коли знайдено найнижчий встановлений біт, у нас є кілька справ. Цей перший фрагмент говорить "якщо у нас встановлений біт ( )і), то припиніть Sпригнічувати результат і tермінізуйте після друку відповіді.

H\\\\\\\/v~a
G\\\\\\/v'
...
A/-'

Незалежно від того, якому біту поточного байта ( A- H) передує лише купа нулів, то один ( \і /: ці погляди на біти безпосередньо на північ від них; ми можемо вірити, що всі попередні біти були нульовими) передається через провід на праворуч ( v,, '...), то яке б значення воно не було перевернене і задається як низький біт виводу ( ~a).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.