Перетворити з бази 10 на базу 2 без вбудованих базових перетворень


16

Фон :

Вам було доручено перетворити базові 10 чисел у базові 2, не використовуючи жодних попередніх функцій перетворення базових даних. Не можна також використовувати жодні імпортовані бібліотеки.

Проблема :

Перетворіть вхідний рядок з бази 10 (десятковий) в базу 2 (двійковий). Ви не можете використовувати будь-який попередньо створений базовий код / ​​функції / методи або імпортовані бібліотеки. Оскільки це , найкоротша відповідь у байтах виграє.

Введенням буде що-небудь від -32768 до 32767 (включити обробку байтів знаків у свій код)


3
Питання: що означає "обробка байтом" - я повинен вивести "-xxxx" для від'ємного числа? Тоді хтось із нас помиляється, в т.ч. мені, коли я
вивожу

Підписати обробку байтів - MSB підписаних змінних контролює, якщо вони негативні
TheDoctor

1
звичайно, але чи потрібно> друкувати <їх як знак '-' з подальшим розмахом?
blabla999

@ blabla999 - Ні, ти не
TheDoctor

3
the MSB of signed variables controls if they are negative- це звучить як бітовий знак, проте, як -32768..32767підказує діапазон , ви хочете доповнити 2. То чого ти хочеш? ..
mniip

Відповіді:


4

GolfScript - 17 байт

~{.1&\2/}16*;]-1%

Не надто багатослівний, ніж вбудований ~2base.


1
Я не знаю golfscript, але кілька запущених зразків підштовхують мене до висновку, що ви повинні видалити~
user12205

@ace Оскільки початковий вхід є рядком "37", наприклад, операція "37" & 1(в infix) є операцією, встановленою набору. ~На фронті перетворює вхідні дані в ціле число.
примо

Я зробив свій тест тут golfscript.apphb.com/… чи означає це, що цей перекладач невірний? (Вибачте, я справді нічого не знаю про golfscript)
користувач12205

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

12

JavaScript, 46

for(x=prompt(o='');x;x>>>=1)o=(x&1)+o;alert(o)

Лол, я навіть не знав, що 4-символьний оператор ( >>>=) існує! +1 (Також, якщо запустити його в консолі, ви можете зберегти останні 9 символів.)
Doorknob

1
Це не чотири символи, це два оператори: >>> - це зсув правильного зсуву 0 заповненням з наступним призначенням. Спробуйте: x=8; x>>>=1; x;і x=8; x>>>1; x;- у першому випадку значення x змінилося; у другій - ні.
Грехем Чарльз

3
@GrahamCharles >>>=- це єдиний оператор .
примо

Ну, подивіться на це! Дякую, @primo ... ти щодня дізнаєшся щось!
Грем Чарльз

2
@ComFreek Це змінило б порядок цифр
скопіюйте

4

Brainf * ck, 98 77

Очевидно, це не для того, щоб виграти, а що б склало змагання, якби у нього не було рішення про brainfk

++++[>++++<-]>>,<[->>++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]++++++[->++++++++<]>.[-]>[-<<<+>>>]<<<<]

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

Це насправді працює для 16-бітного введення, якщо ваш інтерпретатор підтримує

Я навіть отримав це для виведення у значеннях ascii

Ось примітка з кодом:

++[>++++<-]                       preload 8 onto cell 1
>>,<                                input into cell 2
[-                                  iterate over cell 1
    >>++<                               put 2 in cell 3
    [->-[>+>>]>[+[-<+>]>+>>]<<<<<]      division algorithm: converts {n d} into {0 d_minus_n%d n%d n/d}
    >[-]++++++[->++++++++<]>           clears cell 4 and puts 48(ascii of 0) into cell 5
    .[-]                                output n%2 and clear it (the bit)
    >[-<<<+>>>]                         bring n/2 into cell 2 (to be used for division in next iteration)
<<<<]                               end iterate

Коротший алгоритм (77):

+>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+>+>+>+>+>+>+>+<<<<<<<<]>[.>]

Цей може обробляти лише 8-бітні цілі числа.

Алгоритм працює за допомогою двійкового лічильника, який насправді дуже короткий (один приріст, >[->]++[-<+]-<-який потім викладає біти. Проблема полягає в тому, що важко роздрукувати всі біти

Останній алгоритм можна адаптувати під будь-яку кількість бітів за рахунок байтів. Щоб мати можливість працювати з N бітовими цілими числами, для кодування потрібно 53 + 3 * N байт.

приклади:

(1 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+<]>[.>]
(2 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+>+<<]>[.>]
(3 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+>+>+<<<]>[.>]
etc

3

Обов’язкова відповідь APL - 21 22

"01"[1+2|⌊⎕÷2⋆⊖0,⍳15]

Приклади:

      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 0
0000000000000000
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 13
0000000000001101
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 9999
0010011100001111
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: -3
1111111111111101
      "01"[1+2|⌊⎕÷2⋆⊖0,⍳15]
⎕: 32767
0111111111111111

Ви можете скоротити майже 50% при використанні ⎕IO←0, і повертає масив бітів замість рядка: 2|⌊⎕÷2*⊖⍳16.
Адам

3

Код машини Тьюрінга, 272 байти

Як завжди, я використовую синтаксис таблиці правил, визначений тут. Ви можете протестувати його на цьому веб-сайті або, альтернативно, використовувати цю реалізацію Java.

Багато мого коду скопійовано з мого перетворювача десяткової в шестнадцять тут.

0 * * l B
B * * l C
C * 0 r D
D * * r E
E * * r A
A _ * l 1
A * * r *
1 0 9 l 1
1 1 0 l 2
1 2 1 l 2
1 3 2 l 2
1 4 3 l 2
1 5 4 l 2
1 6 5 l 2
1 7 6 l 2
1 8 7 l 2
1 9 8 l 2
1 _ * r Y
Y * * * X
X * _ r X
X _ _ * halt
2 * * l 2
2 _ _ l 3
3 * 1 r 4
3 1 0 l 3
4 * * r 4
4 _ _ r A

Відраховується від входу в базі 10, підраховуючи від 0 в базі 2. Після зменшення нуля він стирає блок введення і закінчується.


2

Javascript 59

o='';i=parseInt(prompt());do{o=(i&1)+o}while(i>>=1)alert(o)

Ви можете використовувати +xзамістьparseInt(x)
Cyoce

2

Перл, 44

Це моя перша програма Perl коли-небудь, тому, будь ласка, пробачте мене, якщо це можна буде легко пропустити далі. Редагувати: Дякую @primo за те, що я забрав 7 знаків від моєї відповіді.

$x=<>;do{@s=($x&1,@s)}while($x>>=1);print@s

$x=<>;do{push@s,$x&1}while($x>>=1);print reverse@s

Логіка по суті така ж, як і моє попереднє рішення C.

Також використовується 64 біт.


1
Ви можете зберегти reverseшляхом побудови масиву в зворотному напрямку: @s=($x&1,@s).
прим

1
Тепер, коли конкурс закінчився, найкращим я знайшов 34 : $\=$_%2 .$\while$_=$_>>1||<>;print. Або, якщо параметри командного рядка рахують один байт, 27: 1while$\=$_%2 .$\,$_>>=1}{використовуючи -p.
примо

2

Javascript - 56 48 та 36 28 символів

  • Не працює з від’ємними числами.

Завдяки @Blender за гоління 8 символів.

Ця форма приймає введення та показує вихід, 48 символів:

x=prompt();for(a="";x;x=~~(x/2))a=x%2+a;alert(a)

Якщо потрібна лише інструкція, яка вводить в змінну aдвійкову форму змінної x(і ви не турбуєтесь у знищенні xзначення як побічного ефекту), то це з 28 символами:

for(a="";x;x=~~(x/2))a=x%2+a

1
Ви можете замінити Math.floorна ~~, оскільки діапазон для чисел невеликий.
Блендер

@Blender Спасибі, я знав, що існує якийсь спосіб, просто не міг його знайти.
Віктор Стафуса

@Victor Я не знаю JavaScript, тому я можу помилитися, але наприкінці, коли ви скажете, чи a=x%2+aможна це скоротити a+=x%2? Він працює всіма мовами, які я знаю.
Альберт Реншо

@AlbertRenshaw Ні, це було б те саме a=a+x%2, але +це для конкатенації рядків. Тобто, ваша пропозиція призводить до цифр у зворотному порядку.
Віктор Стафуса

@Victor Ah! Дякую!
Альберт Реншо

2

Пітон - 61 60 символів

x=input();print"".join("01"[x>>i&1]for i in range(15,-1,-1))

2
Ви можете позбутися місця між printі "".
Блендер

@Blender я збирався запропонувати те саме:
Альберт Реншо

@Blender Ha правда, навіть не помічав. Готово!
C0deH4cker

якщо ви зателефонуєте з командного рядка, ви можете залишити його вбік, printоскільки він автоматично повертає результат
paul.oderso

2

C, 55 символів

Друкує додатковий провідний нуль (ради 2 байти).
Рекурсія всередині printfскасовує порядок друку, тому алгоритм вилучає біти справа наліво, але друкує зліва направо.

EDIT : Збережено знак, використовуючи putcharзамість printf.

f(x){(x*=x<0?-printf("-"):1)&&f(x/2);putchar(48+x%2);}

2

Діалог APL , 11 байт

2|⌊⎕÷2*⌽⍳16

2| Залишок поділу, коли він зменшився вдвічі
закругленого значення
вхідного сигналу
÷ділиться на кожне з
2*двох на потужність кожного з
⍳16{0, 1, 2, ..., 15}

Потрібно, ⎕IO←0що за умовчанням для багатьох систем.

СпробуйтеAPL онлайн!


1

С, 81

char b[17];i=15;main(x){scanf("%d",&x);while(i+1)b[i--]=(x&1)+48,x>>=1;puts(b);}

Вихід має строго 16 біт (включаючи занулення нулів)


1

Службовий сценарій + Google Таблиці, 147 144 121 байт

Сценарій

function j(decNumb){var str='';do{str=String(decNumb%2)+str;decNumb=decNumb/2|0;}while(decNumb>=1);return parseInt(str);}

Лист

=j(b1)

Модифікована версія цього сценарію від ZygD.


Чи можете ви видалити будь-які пробіли?
NoOneIsHere

1

Haskell, 66 байт

c 0=0
c n=c(div n 2)*10+mod n 2
b('-':r)='-':b r
b r=show.c.read$r

Подзвоніть за допомогою b "-1023", додайте main=interact bдля повноцінної програми або спробуйте її на Ideon.

cвиконує перетворення на додатні цілі числа.
b r=show.c.read$rперетворює рядок у число, застосовує cта перетворює назад у рядок.
b('-':r)='-':b rсмужки можливого ведучого -і повторно додають його до результату.


1

PowerShell, 59 87 82 70 байт

+28 байт для підтримки від'ємних чисел.
-12 байт завдяки @ ASCII

param($d)$m=$d-lt0;while($d){$n="01"[$d%2]+$n;$d=($d-$d%2)/2}'-'*$m+$n

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

Адаптовано з цього коду . Здійснює введення через параметр командного рядка -d.


А як щодо цифр зі знаком?
маззи



о зачекайте 70
лише ASCII

1

APL (NARS), 17 символів, 34 байти

{2∣⌊⍵÷2*(⍺-1)..0}

Це копія та модифікація відповіді Адама /codegolf//a/90107 таким чином, як можна додати параметр довжини біт, і ⎕IO для цієї функції (ось ⎕IO = 1) повинен не мають значення ...

  f←{2∣⌊⍵÷2*(⍺-1)..0}
  16 f 2
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
  32 f 2
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 
  32 f ¯1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
  16 f ¯1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
  64 f ¯12345678
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 

Здається, таким чином легко обробити кількість бітів (я підтвердив, що останній результат повинен бути правильним)


0

Smalltalk (Smalltalk / X), 63/78

перша версія створює проміжну рядок (78):

t:=Number readFrom:Stdin.
((15to:1by:-1)collect:[:i|$0+(t>>i&1)]as:String)print

насправді, немає необхідності створювати рядок; просто виведіть символи (63):

t:=Number readFrom:Stdin.
15to:1by:-1 do:[:i|($0+(t>>i&1))print]

mhmh - чи є коротший спосіб читати до числа?


0

Python 3.x: 65 символів

b=lambda n:n<2 and'01'[n]or b(n//2)+b(n%2);print(b(int(input())))

0

Баш, 44

f=b+=n/2**e%2*10**e,2**e++/n?f=b:f;echo $[f]

Передайте вхідне значення сценарію через змінну середовища n. Десяткове представлення двійкового результату не може перевищувати LONG_MAX.

Це також має бути сумісним з ksh93і zshякщо bі eинициализируется 0і використовуються правильне арифметичне розширення.


1
Я не вірю, що це справедливо, оскільки передбачає, що nце вже визначено, що робить його фрагментом. Це можна виправити, взявши введення як аргумент командного рядка та встановивши nйого у вашому сценарії.
спагето

@quartata Змінні в математичному контексті в оболонці неявно дорівнюють нулю. Для гри в гольф має більше сенсу робити n=127 sh -c '...'ніж sh -c 'n=$1 ...' _ 127. У цьому випадку немає жодної причини віддавати перевагу одному над іншим, оскільки вони обидва є ідеально типовим способом передачі значень.
ormaaj

0

C # - 104

string p(int d){var r="";long i=1;while(r.Length<=64){var g=d&i;r=(g!=0)? "1"+r:"0"+r;i=i<<1;}return r;}

Цей метод перетворить десятковий у двійковий до 64бітів.

При виконанні вищевказаного методу в Linqpad - rr = p (-32768); rr.Dump ();

Вихід: 01111111111111111111111111111111111111111111111111000000000000000


Специфікація вимагає "вхідного рядка". Схоже, цей метод приймає int.
Пукайте

0

Java 8, 80 71 байт

n->{String r="";for(int i=n<0?-n:n;i>0;i/=2)r=i%2+r;return n==0?"0":r;}

-9 байтів через правило в коментарях. Негативні базові входи 10 можуть повернути позитивне / абсолютне значення бази-2 як вихідне.

Пояснення:

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

n->{                   // Method with integer parameter and String return-type
  String r="";         //  Result-String, starting empty
  for(int i=n<0?-n:n;  //  Start `i` at the absolute (non-negative) value of the input
      i>0;             //  Loop as long as `i` is not 0
      i/=2)            //    After every iteration: integer-divide `i` by 2
    r=i%2+r;           //   Prepend the result with `i` modulo-2
  return n==0?         //  If the input is 0:
          "0"          //   Return literal "0"
         :             //  Else:
          r;           //   Return the result-String


0

Маленький базовий , 133 байт

Сценарій, який вводить і виводить на TextWindowконсоль.

n=TextWindow.Read()
While n>0
c=c+1
x[c]=Math.Remainder(n,2)
n=Math.Floor(n/2)
EndWhile
For i=0To c-1
TextWindow.Write(x[c-i])
EndFor

Спробуйте це на SmallBasic.com Потрібен Silverlight, і тому його потрібно запускати в IE.

I / O приймається / подається з чорної консолі.

-22 байти завдяки @Neil


Не можете використовувати For i=0To c-1?
Ніл

@Neil - я абсолютно можу. Чудовий улов!
Тейлор Скотт

0

MATL , 15 17 байт

t0<?16Ww+]`2&\t]x

Спробуйте це на MATL Online

ТІО

(+2 байти, видаляючи провідні 0 для негативних чисел, біт знаків повинен бути першим бітом.)

Вихід на MATL Online слід читати знизу вгору (MSB знаходиться внизу).

Основна частина досить проста: `2&\t = поки значення більше 0, розділіть на 2 і накопичіть залишки.

Обробка негативних чисел та надання їх доповненням 2 було складною частиною. Врешті-решт я пішов із « відніманням від2N"метод отримання доповнення числа числа. Оскільки нам потрібно лише обробляти значення до -32768, для негативних чисел код створює 216=65536з 16W, додає вхід до цього (наприклад, 65536 + (-42)), що дає щось, що MATLAB сприймає як позитивне число, але представляє підписане на вході двійкове представлення у 16-бітній формі.




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