Чергування розмазування біт


12

Вступ

Цей виклик вимагає від вас встановити проміжні нулі цілого бінарного представлення на 010101…це, найкраще пояснити на прикладі:

Враховуючи ціле число 400, перший крок - перетворити його на бінарне:

110010000

Як ми бачимо, п'ятий біт є найменш значущим 1бітом, тому, починаючи звідти, ми замінюємо нижні нулі на 0101:

110010101

Нарешті ми перетворюємо це назад у десятковий: 405

Виклик

За умови позитивного цілого повернення / виведення відповідне отримане значення вищеописаного процесу.

Правила

  • Ця послідовність визначена лише для цілих чисел, що мають принаймні один 1біт, тому вхід завжди буде ≥ 1
  • Ви можете замість цього ввести рядок як рядок, список цифр (десяткових)
  • Вам не доведеться обробляти недійсні введення

Тестові шафи

Ось ще кілька тестів із посередницькими кроками (їх не потрібно друкувати / повертати):

In -> … -> … -> Out
1 -> 1 -> 1 -> 1
2 -> 10 -> 10 -> 2
3 -> 11 -> 11 -> 3
4 -> 100 -> 101 -> 5
24 -> 11000 -> 11010 -> 26
29 -> 11101 -> 11101 -> 29
32 -> 100000 -> 101010 -> 42
192 -> 11000000 -> 11010101 -> 213
400 -> 110010000 -> 110010101 -> 405
298 -> 100101010 -> 100101010 -> 298

Чи можна вважати 32-бітне ціле число?
Арнольд

@Arnauld: Звичайно!
ბიმო

9
Деякі ідеї для гольфу: Якщо nмаксимальна потужність 2 ділить вхід, то відповідь просто(input) + ceil((2^n - 2)/3)
JungHwan Min

Відповіді:


12

Python 3 , 20 байт

lambda n:(n&-n)//3+n

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

Пояснення

Візьмемо 192як приклад. Його двійкова форма є 11000000, і нам потрібно її перетворити 11010101.

Відзначимо, що нам потрібно додати 10101число. Це геометричний ряд ( 4^0 + 4^1 + 4^2), який має закриту форму як (4^3-1)/(4-1). Це те саме, що 4^3//3там, де //позначається ціле ділення.

Якби це було 101010 , то це все-таки був би геометричний ряд ( 2×4^0 + 2×4^1 + 2×4^2), що є 2×4^3//3з причин вище.

У всякому разі, 4^3і2×4^3 був би найменш вагомий біт, який ми отримуємо n&-n:

Ми помічаємо, що доповненням nє 00111111. Якщо ми додамо один, він стає 01000000, і він перекривається лише n=11000000принаймні значущою цифрою. Зауважте, що "доповнити та додати одне" - це лише заперечення.


6
@ Mr.Xcoder приємна спортивна майстерність
Leaky Nun

1
Можливо, lambda n:(n&-n)//3+nтеж працює? Проходить усі зразки тестових випадків , але на мою інтуїцію це не повинно бути дійсним, правда?
Містер Xcoder

@ Mr.Xcoder це дійсно дійсно.
Leaky Nun

1
Чому б не використовувати Python 2 для збереження байта? TIO
FlipTack

4
@FlipTack Я ненавиджу python 2
Leaky Nun

8

Желе , 5 байт

&N:3+

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

Цього разу порт підліткової монахині підходить (принаймні, я допоміг йому трохи зіграти: P)

Желе , 7 байт

^N+4:6ạ

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

Використовує фантастичний підхід JungHwan Min з непрямою допомогою Мартіна Ендера .


Денніс опублікував, а потім видалив, дуже схоже 5-байтне рішення відразу після того, як ви зробили цю редагування. Щось подібне &N:3|. Вітаємо; ти побив Денніса в Желі! (Але не зовсім поза межами гольфу.)
wizzwizz4

@ wizzwizz4 Я насправді нічого не зробив, окрім запропонувавши маленький гольф до підходу Лікі, а потім перенести його. Але так :-)
Містер Xcoder

Це перша відповідь лише для ASCII, яку я коли-небудь бачив.
MD XF

6

Мова Вольфрама (Mathematica) , 36 28 26 24 байт

-8 байт завдяки @MartinEnder і -2 байти завдяки @ Mr.Xcoder

#+⌊(#~BitAnd~-#)/3⌋&

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

Нам потрібно лише знайти число кінцевих нулів на вході та знайти число з чергуванням 0s та1 s довжиною на одиницю менше, ніж його, і додати його до вводу.

Так, 400 -> 11001000 -> 110010000 + 0000 -> 110010101 + 101 -> 405

Явна формула для nчисла з чергуванням 1s і 0s була наведена в A000975 на OEIS. Ми можемо використовувати nth число, оскільки жодне два різних числа не може мати однакову довжину у двійкових і мати чергуються цифри.


1
2^#~IntegerExponent~2є(BitXor[#,#-1]+1)/2
Мартін Ендер

@MartinEnder вау! І тоді я можу просто об’єднати дроби, щоб зменшити більше байтів
JungHwan Min

1
24 байти . Ви можете використовувати #+⌊(#~BitAnd~-#)/3⌋&замість цього.
Містер Xcoder

@ Mr.Xcoder відредаговано :)
JungHwan Min

5

J , 19 18 байт

+(2|-.i.@#.-.)&.#:

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

Швидке пояснення

Це стара відповідь, але вона за своєю суттю дуже схожа на поточну, вона просто рахує останні нулі по-різному. Дивіться коментарі до посилання, що пояснює, як це працює.

+(2|i.@i.&1@|.)&.#:
                 #:  Convert to binary list
       i.&1@|.       Index of last 1 from right
            |.         Reverse
       i.&1            Index of first 1
    i.               Range [0, index of last 1 from right)
  2|                 That range mod 2
               &.    Convert back to decimal number
+                    Add to the input

Інші відповіді:

Попередня відповідь (19 байт).

+(2|i.@i.&1@|.)&.#:

Довше, ніж має бути, тому що \йде справа наліво.

+(2|#*-.#.-.)\&.(|.@#:)

1
18 байт+(2|-.i.@#.-.)&.#:
миль

@miles розум пояснює, що відбувається з базовим перетворенням там? Я здогадуюсь, що це щось стосується нулів, але я не впевнений.
Коул

#.~ підраховує кількість останніх істин , тож нам потрібно #.~ -. #:порахувати кількість кінцевих нулів
миль

@miles Ах! Це дуже, дуже розумно.
Коул

4

Це виглядає як ефективний метод, чи можете ви пояснити перевагу оператора? Наприклад, я не можу сказати, чи оцінюється це як ((!n=(n|n))&-n)/3, або !n=(((n|n)&(-n))/3)тощо
MD XF

У Джулії бітові оператори мають ті ж переваги, що й їхні арифметичні аналоги, так |це схоже +і &схоже *. Тому n|n&-n÷3розбирається як n | ((n&-n) ÷3).
Денніс

3

JavaScript (ES6), 40 39 байт

Вводиться як 32-бітове ціле число.

n=>n|((n&=-n)&(m=0xAAAAAAAA)?m:m/2)&--n

Тестові справи


2

05AB1E , 13 8 5 байт

Збережено 5 байт завдяки акуратній формулі містера Xcoder та JungHwan Min.
Збережено ще 3 подяки містеру Xcoder

(&3÷+

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

Пояснення

(      # negate input
 &     # AND with input
  3÷   # integer divide by 3
    +  # add to input

1
Можливо, варто згадати, що перенесення відповіді Mathematica дає 8 байт
містер Xcoder

@ Mr.Xcoder: О, це акуратна формула.
Емінья

1
Чи має біт 05ab1e І? Якщо так, (<bitwise and here>3÷+слід працювати на ~ 5 байт.
Містер Xcoder

2

R , 71 58 байт

завдяки NofP за -6 байт

function(n){n=n%/%(x=2^(0:31))%%2
n[!cumsum(n)]=1:0
n%*%x}

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

Припускає, що вхід - це 32-бітове ціле число. R doubleвсе одно має підписані 32-бітні цілі числа (відкликання, коли ціле число переповнюється) у будь-якому випадку, і немає 64-бітових або неподписаних вкладених елементів.


Ви можете перетворити which.max(n):1-1на, !cumsum(n)щоб отримати рішення в 65 байт
NofP

@NofP дякую! Це чудова ідея.
Джузеппе

2

мозковий ебать , 120 байт

>+<[[>-]++>[[>]>]<[>+>]<[<]>-]>[-<+>[-<[<]<]>]>[>]<[>+<[->+<]<[->+<]<]>>[<]+>[-[-<[->+<<+>]>[-<+>]]<[->++<]<[->+<]>>>]<<

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

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


1

PowerShell , 168 байт

param($n)$a=($c=[convert])::ToString($n,2);if(($x=[regex]::Match($a,'0+$').index)-gt0){$c::ToInt32(-join($a[0..($x-1)]+($a[$x..$a.length]|%{(0,1)[$i++%2]})),2)}else{$n}

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

Ой. Перетворення на / з бінарного та нарізання масивів насправді не є сильними костюмами PowerShell.

Вводиться $nяк число. Ми негайно convertце до двійкової бази 2і зберігаємо це в $a. Далі ми маємо конструкцію if / else. Стаття if перевіряє, чи має a regex Matchпроти 1 або більше 0s в кінці рядка ( '0+$') indexрозташування більше 0(тобто початок двійкового рядка). Якщо це так, нам є над чим працювати, elseми просто виводимо число.

Всередині if, ми нарізаємо xперші цифри та з'єднуємо +ті, що залишилися. Однак для решти цифр ми перебираємо їх і вибираємо або a, 0або 1виводимо натомість, використовуючи $i++%2для вибору. Це отримує нам 010101...візерунок замість 0s в кінці. Потім ми -joinповертаємо їх назад в рядок і $cповертаємо його назад в Int32основу 2.

В будь-якій ситуації кількість залишається на трубопроводі, а вихід непрямий.


1

APL + WIN, 43 байти

p←+/^\⌽~n←((⌊1+2⍟n)⍴2)⊤n←⎕⋄2⊥((-p)↓n),p⍴0 1

Підказки для введення екрана









1

JavaScript ES6, 13 байт

n=>(n&-n)/3|n

f = 
n=>(n&-n)/3|n
;
console.log (f(8));
console.log (f(243));
console.log (f(1048576));
console.log (f(33554432));


1

C, 56 байт

i,k;f(n){for(k=i=1;n>>i<<i==n;k+=++i&1)k*=2;return n|k;}

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

C (gcc), 50 байт

i,k;f(n){for(k=i=1;n>>i<<i==n;k+=++i&1)k*=2;k|=n;}

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

 51  48 байт за допомогою рішення Арнальда :

Завдяки @ l4m2 за збереження трьох байтів!

m;f(n){return n|((n&-n)&(m=-1u/3*2)?m:m/2)&n-1;}

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

43 з gcc:

m;f(n){m=n|((n&-n)&(m=-1u/3*2)?m:m/2)&n-1;}

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


0xAAAAAAAA=>-1u/3*2
l4m2


0

Желе , 13 байт

BŒgṪµ2Ḷṁ×CḄ+³

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

Пояснення

Взяти для прикладу 24.

BŒgṪµ2Ḷṁ×CḄ+³
B                Binary representation of the input → 11000
 Œg              Group runs of equal length → [[1,1],[0,0,0]]
   Ṫ             Tail → [0,0,0]
    µ            New monadic link
     2Ḷ          [0,1] constant
       ṁ         Mold [0,1] to the shape of [0,0,0] → [0,1,0]
        ×        Multiply [0,1,0] by...
         C       1-[0,0,0]. If last bit(s) of the original input are 1 this will add nothing to the original input
          Ḅ      Convert to decimal from binary → 2
           +³    Add this with the original input → 26
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.