Що таке зворотне (двійкове) бітове число?


33

Отже, вам надається ПОЗИТИВНЕ базове 10 (десяткове) число. Ваше завдання - перевернути двійкові цифри та повернути базове 10 число.

Приклади:

1 => 1 (1 => 1)
2 => 1 (10 => 01)
3 => 3 (11 => 11)
4 => 1 (100 => 001)
5 => 5 (101 => 101)
6 => 3 (110 => 011)
7 => 7 (111 => 111)
8 => 1 (1000 => 0001)
9 => 9 (1001 => 1001)
10 => 5 (1010 => 0101)

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

Це A030101 в OEIS.


2
Чи означає "зворотний біт" означає зворотний його двійкові цифри? Іноді це також може означати інвертування кожного шматочка .
ETHproductions

Так. Вибачте за незрозумілість.
молодшийРубіїст

Це та це veeeeery схоже.
Геобіц


1
"База 10" З якоїсь конкретної причини?
КалькуляторFeline

Відповіді:


20

Пітон , 29 байт

lambda n:int(bin(n)[:1:-1],2)

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

Це анонімна неназвана функція, яка повертає результат.


Спочатку bin(n)перетворює аргумент у двійковий рядок. Зазвичай ми б це перетворили за допомогою позначення фрагмента [::-1]. Це читає рядок з кроком -1 , тобто назад. Однак бінарні рядки в Python мають префікс an 0b, і тому ми даємо другий аргумент нарізки як 1 , кажучи Python читати назад, що закінчується в індексі 1 , таким чином, не зчитуючи індекси 1 і 0 .

Тепер, коли ми маємо зворотний двійковий рядок, передаємо його int(...)з другим аргументом як 2 . Це читає рядок як ціле число базового 2, яке потім імплікація повертається лямбда-виразом.


2
Бити вас за 9 секунд.
mbomb007


6
@ mbomb007, тож моя відповідь недійсна, тому що ви натиснули кнопку публікації за 9 секунд перед рукою? Це те, що ми одночасно дістаємось до того самого гольфу, не означає, що ми повинні видаляти відповіді. Якщо що, звинувачуйте в питанні 0 зусиль.
FlipTack

3
Не інвалідні, але, безумовно, безглузді. Якби я була повільнішою, я просто видалила б свою та опублікувала коментар до того швидшого, який я теж придумала.
mbomb007

1
@steenbergh Кого хвилює? Той самий код, однаковий бал.
mbomb007


13

JavaScript (ES6), 30 28 байт

Збережено 2 байти завдяки @Arnauld

f=(n,q)=>n?f(n>>1,q*2|n%2):q

Це в основному обчислює зворотний один біт за один раз: Почнемо з q = 0 ; в той час як п позитивна, ми помножити д на 2, відсікти останній біт геть п з n>>1, і додати його в д з |n%2. Коли n досягає 0, число було успішно перетворено, і повертаємо q .

Завдяки довгим вбудованим іменам JS, вирішення цього завдання найпростішим способом займає 44 байти:

n=>+[...n.toString(2),'0b'].reverse().join``

Використовуючи рекурсію та рядок, ви можете отримати 32-байтне рішення, яке робить те саме:

f=(n,q='0b')=>n?f(n>>1,q+n%2):+q

f=(n,q)=>n?f(n>>1,q*2|n%2):qмайже працює. Але, на жаль, не для n=0.
Арнольд

@Arnauld OP ще не відповів, чи буде вхід завжди позитивним, але якщо так, то 0 не потрібно обробляти.
FlipTack

Це пізнє спостереження, але тепер відомо, що цей вклад завжди позитивний.
Арнольд

@Arnauld Дякую!
ETHproductions

10

Java 8, 53 47 46 45 байт

  • -4 байти завдяки Титу
  • -1 байт завдяки Kevin Cruijssen

Це лямбда-вираз, який має той самий принцип, що і відповідь ETH (хоча рекурсія була б занадто багатослівною в Java, тому ми замість цього циклу):

x->{int t=0;for(;x>0;x/=2)t+=t+x%2;return t;}

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

Це можна призначити за допомогою IntFunction<Integer> f = ..., а потім викликати за допомогою f.apply(num). Розгорнутий, неозорений та прокоментований, це виглядає приблизно так:

x -> { 
    int t = 0;           // Initialize result holder   
    while (x > 0) {      // While there are bits left in input:
        t <<= 1;         //   Add a 0 bit at the end of result
        t += x%2;        //   Set it to the last bit of x
        x >>= 1;         //   Hack off the last bit of x
    }              
    return t;            // Return the final result
};

1
Збережіть 3 байти, t*2а (t<<1)не ще один, перемістивши цей обчислення від голови циклу до тіла циклу. Чи можете ви використовувати xзамість x>0умови?
Тит

2
@Titus не без явного виступу булевого, але дякую за інші поради! Також щойно зрозумів, що x>>=1його можна замінити, x/=2оскільки це автоматично буде ціле ділення.
FlipTack

45 байт (Змінено t=t*2+на t+=t+.)
Кевін Кройсейсен

@KevinCruijssen приємний!
FlipTack




7

Лабіринт, 23 байти

?_";:_2
  :   %
 @/2_"!

Ну, це незручно ... це повертає зворотний БІНАРИЙ номер ... Дякую @Martin Ender за вказівку і на мою помилку, і на мою помилку 10T ID. Тож це не працює, мені доведеться знайти інше рішення.


1
Ласкаво просимо до PPCG та приємного першого повідомлення! Просто виконати виклик такою мовою, як Лабіринт, може бути дуже важко. Навколо ми зазвичай префіксуємо перший рядок відповіді одним або двома хешами, щоб він відображався як заголовок:# Labyrinth, 89 bytes
ETHproductions

1
Ви випадково пропустили провідний пробіл з другого ряду? На даний момент програма просто відскакує вперед і назад на першому рядку, оскільки вони _перебувають на стиках.
Мартін Ендер

На жаль, я щойно помітив, що це не вірно незалежно, оскільки виклик вимагає представлення базового 10 перевернутого числа, а не його бінарного подання.
Мартін Ендер

6

C, 48 44 43 42 байт

-1 байт завдяки гурці та -1 байт завдяки анатолігу:

r;f(n){for(r=n&1;n/=2;r+=r+n%2);return r;}

Попереднє рішення 44 байти:

r;f(n){r=n&1;while(n/=2)r=2*r+n%2;return r;}

Попереднє 48 байт рішення:

r;f(n){r=0;while(n)r=2*(r+n%2),n/=2;return r/2;}

Безголовка та використання:

r;
f(n){
 for(
  r=n&1;
  n/=2;
  r+=r+n%2
 );
 return r;}
}


main() {
#define P(x) printf("%d %d\n",x,f(x))
P(1);
P(2);
P(3);
P(4);
P(5);
P(6);
P(7);
P(8);
P(9);
P(10);
}

Тут rвже не ініціалізовано до нуля r;f(n){r=0;, наприкладr=0; , непотрібне? Також незначна помилка: "Попереднє розв’язання 48 байтів"
симон

1
@gurka Функція повинна бути багаторазовою.
Карл Напф

1
Я думаю, що forпетлі завжди принаймні короткі, ніж whileпетлі, і часто коротші.
анатоліг

@anatolyg щось на кшталт r;f(n){for(r=n&1;n/=2;r=2*r+n%2);return r;}:? 1 байт коротше, але я не впевнений, чи дійсний це C (C99).
симон

Так; також перетворіть =його, +=щоб зробити його коротшим і більш затуманеним
затуманеним

5

Рубі, 29 28 байт

->n{("%b"%n).reverse.to_i 2}

"% b"% n форматує вхід n як двійковий рядок, обернеться назад, а потім перетворить назад у число

Використання / Тестові випадки:

m=->n{("%b"%n).reverse.to_i 2}
m[1] #=> 1
m[2] #=> 1
m[3] #=> 3
m[4] #=> 1
m[5] #=> 5
m[6] #=> 3
m[7] #=> 7
m[8] #=> 1
m[9] #=> 9
m[10] #=> 5

@Titus Я думаю, що ти неправильно зрозумів відповідь. 2є базою, в яку він перетворюється, і nє входом. ->args{return value}є синтаксисом ламбда рубіну
Cyoce

Чи можете ви видалити дужки в .to_i(2)?
Кіос

@Cyoce впевнений, дякую.
Алексіс Андерсен


4

Java (OpenJDK) , 63 байти

a->a.valueOf(new StringBuffer(a.toString(a,2)).reverse()+"",2);

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

Завдяки ткюку на -12 байт та Cyoce на -8 байт!


Незважаючи на те, що подання REPL дозволено, вони все ще дотримуються правила, згідно з яким ви не можете вважати, що вхід знаходиться у заздалегідь визначених змінних (як aу цьому контексті)
FlipTack

@FlipTack На жаль. Спочатку це було функцією, перш ніж я згадав про існування відбиття
Павло

1
Також надалі використовуйте printзамість printlnгольфу :)
FlipTack

1
StringBufferекономить байт понадStringBuilder
Poke

1
Ви могли б зробити +""замість цього .toString()?
Кіос

3

Perl 6 , 19 байт

{:2(.base(2).flip)}

Де вхід?
Тит

Це функція, яка приймає один параметр $_. Він не згадується по імені, але baseметод викликається на ньому.
Шон

2
@Titus у Perl 6 a Block - це тип коду, який означає, що це об'єкт, що викликається. Вищенаведене - це вираз, який ви можете взяти та призначити змінній на зразок функції або лямбда на іншій мові, або зателефонувати безпосередньо - {:2(.base(2).flip)}(10)на REPL буде надруковано 5. Отже, вона відповідає стандартним критеріям коду-гольфу для функції.
варення

3

Haskell, 36 байт

0!b=b
a!b=div a 2!(b+b+mod a 2)
(!0)

Той самий алгоритм (і довжина!), Як і відповідь JavaScript ETHproductions .



3

PHP, 33 байти

<?=bindec(strrev(decbin($argn)));

перетворити в base2, зворотний рядок, перетворити в десятковий. Збережіть у файл та запустіть як pipe -F.

немає вбудованих:

ітеративний, 41 байт

for(;$n=&$argn;$n>>=1)$r+=$r+$n%2;echo$r;

Поки для введення встановлено біти, вискочіть трохи з введення та натисніть на вихід. Запустити як труба -nR.

рекурсивна, 52 байти

function r($n,$r=0){return$n?r($n>>1,$r*2+$n%2):$r;}

@ JörgHülsermann У 44 байтах є $r+=$r. Але я насправді не пам'ятаю, чому я ставлю це попереду.
Тит




2

Scala, 40 байт

i=>BigInt(BigInt(i)toString 2 reverse,2)

Використання:

val f:(Int=>Any)=i=>BigInt(BigInt(i)toString 2 reverse,2)
f(10) //returns 5

Пояснення:

i =>          // create an anonymous function with a parameter i
  BigInt(       //return a BigInt contructed from
    BigInt(i)     //i converted to a BigInt
    toString 2    //converted to a binary string
    reverse       //revered
    ,           
    2             //interpreted as a binary string
  )


1

Groovy, 46 байт

{0.parseInt(0.toBinaryString(it).reverse(),2)}

Це займає якийсь внесок?
Тит

1
@Titus itпосилається на аргумент, поданий до блоку IIRC
Cyoce

Мені подобається, як це така ж довжина, як і моя відповідь на Java - Java і groovy, єднайтеся!
FlipTack

1
@FlipTack Я зараз буду плакати.
Чарівна восьминога Урна


1

Пакетна, 62 байти

@set/an=%1/2,r=%2+%1%%2
@if %n% gtr 0 %0 %n% %r%*2
@echo %r%

Пояснення: На першому проході %1містить вхідний параметр, поки %2він порожній. Тому ми оцінюємо nяк половину %1і rяк +%1модуль 2 ( %оператор повинен бути подвоєний, щоб процитувати це). Якщо nне дорівнює нулю, ми називаємо себе хвостом, який рекурсивно проходить, nі вираз, який оцінюється при наступному проході, ефективно подвоюється rкожного разу.



1

R, 55 байт

sum(2^((length(y<-rev(miscFuncs::bin(scan()))):1)-1)*y)

Читає вхід з stdin і, отже, використовує binфункцію з miscFuncsпакету для перетворення з десяткового в двійковий вектор.


1

Пушистий , 19 байт

Немає вбудованої базової конверсії!

$&2%v2/;FL:vK2*;OS#

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

У Pushy є два стеки, і ця відповідь широко використовує це.

У цій програмі є дві частини. По-перше, $&2%v2/;Fперетворює число у його зворотне бінарне подання:

            \ Implicit: Input is an integer on main stack.
$      ;    \ While i != 0:
 &2%v       \   Put i % 2 on auxiliary stack
     2/     \   i = i // 2 (integer division)
        F   \ Swap stacks (so result is on main stack)

З огляду на приклад 10, стеки виглядатимуть як наступні на кожній ітерації:

1: [10]
2: []

1: [5]
2: [0]

1: [2]
2: [0, 1]

1: [1]
2: [0, 1, 0]

1: [0]
2: [0, 1, 0, 1]

Ми можемо бачити, що після остаточної ітерації 0, 1, 0, 1було створено другий стек - зворотні двійкові цифри 10 0b1010,.

Друга частина коду, L:vK2*;OS#взята з моєї попередньої відповіді, яка перетворює двійкове в десяткове . Використовуючи метод, розкритий і пояснений у цій відповіді, він перетворює двійкові цифри на стеку в ціле число базового 10 і друкує результат.



0

C #, 167 байт

 for(int i = 1; i <= 10; i++)
 {
 var bytes= Convert.ToString(i, 2);
 var value= Convert.ToInt32(byteValue.Reverse()); 
 console.WriteLine(value);
}

Пояснення:

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


1
Ласкаво просимо на сайт! Я мало знаю про C #, але у вас, звичайно, є багато зайвого простору, я б рекомендував видалити. Також незрозуміло, як вводиться / виводиться справа в цьому поданні. Стандартно або писати функцію, або використовувати STDIN(я думаю, що це, console.Read()але ви, мабуть, знаєте краще, ніж я) і STDOUT. У будь-якому випадку, ласкаво просимо на сайт, якщо ви хочете отримати досвідченіші поради з гольфу C #, я б рекомендував codegolf.stackexchange.com/questions/173/…
пшеничний майстер

Я спростував цю відповідь, бо вона взагалі не працює. .Reverse()повернуті IEnumerable<char>. ЯкConvert.ToInt32 не має перевантаження для IEnumerable, це кидає виняток. Також відповідь не відповідає правилам для коду гольфу: 1) Оскільки нічого не вказано, подання повинно бути повноцінною програмою або функцією, а не лише фрагментом. 2) usingзаяви повинні бути включені до числа байтів
рознагул

0

c / c ++ 136 байт

uint8_t f(uint8_t n){int s=8*sizeof(n)-ceil(log2(n));n=(n&240)>>4|(n&15)<<4;n=(n&204)>>2|(n&51)<<2;n=(n&172)>>1|(n&85)<<1;return(n>>s);}

Це не виграє, але я хотів застосувати інший підхід у c / c ++ 120 байтів у функції

#include <math.h>
#include <stdio.h>
#include <stdint.h>

uint8_t f(uint8_t n){
    int s=8*sizeof(n)-ceil(log2(n));
    n=(n&240)>>4|(n&15)<<4;
    n=(n&204)>>2|(n&51)<<2;
    n=(n&172)>>1|(n&85)<<1;
    return (n>>s);
}

int main(){
    printf("%u\n",f(6));
    return 0;
}

Щоб детальніше розповісти про те, що я роблю, я використовував функцію журналу, щоб визначити кількість бітів, використаних вхідними даними. Чим є серія з трьох бітових зсувів вліво / вправо, всередині / зовні, парне / непарне, яке перевертає все ціле число. Нарешті трохи зсув, щоб перенести число назад вправо. Використання десяткових знаків для зсуву бітів замість шістнадцяткових - це біль, але це заощадило кілька байт.


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