Konwertuj z bazy 10 na bazę 2 bez wbudowanych konwersji bazowych

16

Tło :

Otrzymałeś zadanie konwersji liczb podstawowych 10 na bazę 2 bez korzystania z wcześniej przygotowanych funkcji konwersji bazy. Nie można również używać żadnych importowanych bibliotek.

Problem :

Konwertuj ciąg wejściowy z podstawy 10 (dziesiętnie) na podstawę 2 (binarnie). Nie możesz używać żadnego wcześniej przygotowanego podstawowego kodu konwersji / funkcji / metod ani importowanych bibliotek. Ponieważ jest to , wygra najkrótsza odpowiedź w bajtach.

Dane wejściowe będą mieć wartość od -32768 do 32767 (obejmują obsługę bajtów znaków w kodzie)

Doktor
źródło
3
P: Co oznacza „obsługa bajtów znakowych” - czy mam wypisać „-xxxx” dla liczby ujemnej? Więc niektórzy z nas się mylą, w tym. ja, gdy
wypisuję
Obsługa bajtów znaków - MSB podpisanych zmiennych kontroluje, czy są one ujemne
TheDoctor
1
jasne, ale czy muszę> wydrukować <jako znak „-”, a następnie wielkość?
blabla999
@ blabla999 - Nie, nie masz
TheDoctor
3
the MSB of signed variables controls if they are negative- Brzmi to trochę jak znak, jednak, jak -32768..32767sugeruje zakres , chcesz uzupełnienia 2. Więc czego chcesz? ..
mniip

Odpowiedzi:

4

GolfScript - 17 bajtów

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

Nie za dużo bardziej gadatliwy niż wbudowany ~2base.

primo
źródło
1
Nie znam gry w golfa, ale kilka przykładowych przebiegów doprowadziło mnie do wniosku, że należy usunąć~
user12205
@ace Ponieważ początkowe dane wejściowe są ciągiem znaków "37", na przykład operacja "37" & 1(infiks) jest operacją ustawioną. Z ~przodu konwertuje dane wejściowe na liczbę całkowitą.
primo
Zrobiłem tutaj test golfscript.apphb.com/... czy to oznacza, że ​​ten tłumacz jest niepoprawny? (Przepraszam, naprawdę nie wiem nic o golfscript)
user12205
2
Tłumacz jest poprawny; ponieważ wypchnąłeś wartość całkowitą 10na stos, nie trzeba jej oceniać. Jednak po odczytaniu z stdindanych wejściowych będzie ciąg znaków ( przetestuj tutaj ). Opis problemu również wyraźnie stwierdza, że ​​dane wejściowe są ciągiem.
primo
12

JavaScript, 46

for(x=prompt(o='');x;x>>>=1)o=(x&1)+o;alert(o)
Kopiuj
źródło
Lol, nawet nie wiedziałem, że istnieje 4-znakowy operator ( >>>=)! +1 (Ponadto, jeśli uruchomisz go w konsoli, możesz zapisać 9 ostatnich znaków.)
Klamka
1
To nie są 4 znaki, to dwa operatory: >>> to bitowe prawe przesunięcie wypełniające 0, po którym następuje przypisanie. Spróbuj: x=8; x>>>=1; x;i x=8; x>>>1; x;- w pierwszym przypadku wartość x uległa zmianie; po drugie nie.
Graham Charles
3
@GrahamCharles >>>=jest pojedynczym operatorem .
primo
Spójrz na to! Dzięki, @primo ... uczysz się czegoś każdego dnia!
Graham Charles
2
@ComFreek To odwróciłoby kolejność cyfr
skopiuj
4

Brainf * ck, 98 77

Oczywiście nie ma to na celu wygrania, ale czym byłaby konkurencja, gdyby nie miała rozwiązania dla mózgu

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

Ponieważ brainfk może obsłużyć tylko 8-bitowe liczby całkowite i żadnych negatywów, myślę, że nie w pełni przestrzega zasad, ale hej, nigdy nie byłem w stanie go wygrać.

To faktycznie działa dla 16-bitowego wejścia, jeśli twój interpreter obsługuje

Mam go nawet na wyjście w wartościach ascii

Oto kod z adnotacjami:

++[>++++<-]                       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

Krótszy algorytm (77):

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

Ten obsługuje tylko liczby całkowite 8bit.

Algorytm działa przy użyciu licznika binarnego, który jest w rzeczywistości bardzo krótki (jest to jeden przyrost, >[->]++[-<+]-<-który następnie określa bity. Problem polega na tym, że trudno jest wydrukować wszystkie bity

Ten ostatni algorytm można dostosować do dowolnej liczby bitów kosztem bajtów. Aby móc poradzić sobie z N bitami całkowitymi, wymaga 53 + 3 * N bajtów do zakodowania.

przykłady:

(1 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+<]>[.>]
(2 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+>+<<]>[.>]
(3 bit) +>,>-<[>>[->]++[-<+]-<-]++++++++[->++++++<]>+[->+>+>+<<<]>[.>]
etc
ZAPYTAJ
źródło
3

Obowiązkowa odpowiedź APL - 21 22

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

Przykłady:

      "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
mniip
źródło
Można zmniejszyć o prawie 50% za pomocą ⎕IO←0, i powrót tablicę bitów zamiast ciąg: 2|⌊⎕÷2*⊖⍳16.
Adám,
3

Kod maszynowy Turinga, 272 bajty

Jak zwykle używam zdefiniowanej tutaj składni tabeli reguł . Możesz to przetestować na tej stronie lub, alternatywnie, za pomocą tej implementacji Java.

Dużo kodu jest tutaj kopiowane z mojego konwertera dziesiętnego na szesnastkowy .

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

Odlicza od wejścia w bazie 10, odliczając w górę od 0 w bazie 2. Po zmniejszeniu zera kasuje blok wejściowy i kończy się.

SuperJedi224
źródło
2

JavaScript 59

o='';i=parseInt(prompt());do{o=(i&1)+o}while(i>>=1)alert(o)
Michael M.
źródło
Możesz użyć +xzamiastparseInt(x)
Cyoce,
2

Perl, 44

To jest mój pierwszy program w języku Perl, więc wybacz mi, jeśli można go dalej zagrać w golfa. Edycja: Dziękuję @primo za usunięcie 7 znaków z mojej odpowiedzi.

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

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

Logika jest zasadniczo taka sama jak w moim poprzednim rozwiązaniu C.

Ponadto używa 64 bitów.

użytkownik12205
źródło
1
Można zapisać reversekonstruując kierunku do tyłu tablicy: @s=($x&1,@s).
primo
1
Teraz, że konkurs się skończył, najlepszy znalazłem 34: $\=$_%2 .$\while$_=$_>>1||<>;print. Lub, jeśli opcje wiersza poleceń liczą po jednym bajcie, 27: 1while$\=$_%2 .$\,$_>>=1}{używając -p.
primo
2

JavaScript - 56 48 i 36 28 znaków

  • Nie działa z liczbami ujemnymi.

Dzięki @Blender za golenie 8 znaków.

Ten formularz pobiera dane wejściowe i wyświetla dane wyjściowe, 48 znaków:

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

Jeśli potrzebna jest tylko instrukcja, która umieszcza zmienną, abinarna postać zmiennej x(i nie zawracasz sobie głowy niszczeniem xwartości jako efektem ubocznym), oto 28 znaków:

for(a="";x;x=~~(x/2))a=x%2+a
Victor Stafusa
źródło
1
Można wymienić Math.floorz ~~, gdyż zakres numerów jest niewielka.
Blender
@Blender Dzięki, wiedziałem, że istnieje jakiś sposób, po prostu nie mogłem go znaleźć.
Victor Stafusa
@Victor Nie znam javascript, więc mogę się mylić, ale na koniec, kiedy mówisz, czy a=x%2+amożna to skrócić a+=x%2? Działa we wszystkich językach, które znam.
Albert Renshaw
@AlbertRenshaw Nie, to byłoby to samo a=a+x%2, ale +dotyczy łączenia łańcuchów. Tj. Twoja sugestia skutkuje cyframi w kolejności wstecznej.
Victor Stafusa,
@Victor Ah! Dziękuję Ci!
Albert Renshaw
2

Python - 61 60 znaków

x=input();print"".join("01"[x>>i&1]for i in range(15,-1,-1))
C0deH4cker
źródło
2
Możesz pozbyć się przestrzeni pomiędzy printi "".
Blender
@Blender Właśnie miałem zasugerować to samo :)
Albert Renshaw
@Blender Ha to prawda, nawet nie zauważyłem. Gotowy!
C0deH4cker
jeśli wywołasz go z wiersza poleceń, możesz odłożyć printna bok, ponieważ automatycznie zwraca wynik
paul.oderso
2

C, 55 znaków

Wyświetla dodatkowe wiodące zero (ze względu na 2 bajty).
Rekurencja wewnątrz printfodwraca kolejność drukowania, więc algorytm wyodrębnia bity od prawej do lewej, ale drukuje od lewej do prawej.

EDYCJA : Zapisano znak, używając putcharzamiast printf.

f(x){(x*=x<0?-printf("-"):1)&&f(x/2);putchar(48+x%2);}
ugoren
źródło
2

Dyalog APL , 11 bajtów

2|⌊⎕÷2*⌽⍳16

2|Pozostała część podziału po podzieleniu o połowę
zaokrąglonej wartości
wejściowej
÷podzielonej przez każde z
2*dwóch do potęgi każdego z nich
⍳16 {0, 1, 2, ..., 15}

Wymaga ⎕IO←0ustawienia domyślnego w wielu systemach.

Wypróbuj APL online!

Adám
źródło
1

C, 81

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

Dane wyjściowe mają ściśle 16 bitów (łącznie z zerami wypełniającymi)

użytkownik12205
źródło
1

Aplikacje Script + Arkusze Google, 147 144 121 bajtów

Scenariusz

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

Arkusz

=j(b1)

Zmodyfikowana wersja tego skryptu autorstwa ZygD.

weatherman115
źródło
Czy możesz usunąć jakieś spacje?
NoOneIsHere
1

Haskell, 66 bajtów

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

Zadzwoń b "-1023", dodaj main=interact bkompletny program lub wypróbuj go w Ideon.

cwykonuje konwersję dla dodatnich liczb całkowitych.
b r=show.c.read$rkonwertuje ciąg na liczbę, stosuje ci konwertuje z powrotem na ciąg.
b('-':r)='-':b rusuwa ewentualne prowadzenie -i ponownie dołącza je do wyniku.

Laikoni
źródło
1

PowerShell, 59 87 82 70 bajtów

+28 bajtów do obsługi liczb ujemnych.
-12 bajtów dzięki tylko @ ASCII

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

Wypróbuj online!

Zaadaptowano z tego kodu . Pobiera dane wejściowe za pomocą parametru wiersza polecenia -d.

Gabriel Mills
źródło
Co z liczbami ze znakiem?
mazzy
73?
Tylko ASCII,
och czekaj 70
tylko ASCII
1

APL (NARS), 17 znaków, 34 bajty

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

Jest to kopia i modyfikacja odpowiedzi Adama /codegolf//a/90107 w sposób, w jaki można dodać parametr dla długości bitów, a ⎕IO dla tej funkcji (tutaj jest ⎕IO = 1) powinien nie mają znaczenia ...

  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 

wydaje się, że łatwo jest obsługiwać liczbę bitów w ten sposób (sprawdziłem, że ostatni wynik powinien być prawidłowy)

RosLuP
źródło
0

Smalltalk (Smalltalk / X), 63/78

pierwsza wersja tworzy łańcuch pośredni (78):

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

w rzeczywistości nie ma potrzeby tworzenia łańcucha; po prostu wypisz znaki (63):

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

mhmh - czy istnieje krótszy sposób na odczytanie liczby?

blabla999
źródło
0

Python 3.x: 65 znaków

b=lambda n:n<2 and'01'[n]or b(n//2)+b(n%2);print(b(int(input())))
dan04
źródło
0

Bash, 44

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

Przekaż wartość wejściową do skryptu za pomocą zmiennej środowiskowej n. Reprezentacja dziesiętna wyniku binarnego nie może przekraczać LONG_MAX.

To powinno być również zgodne z ksh93a zshjeśli bi esą inicjowane 0i właściwe rozszerzenie arytmetyka jest używany.

ormaaj
źródło
1
Nie wierzę, że jest to poprawne, ponieważ zakłada, że njest już zdefiniowane, co czyni go fragmentem. Można to naprawić, przyjmując dane wejściowe jako argument wiersza poleceń i ustawiając nje w skrypcie.
spaghetto
@ quartata Zmienne w kontekście matematycznym w powłoce są domyślnie zerowe. Dla golfa sensowniejsze jest robienie tego n=127 sh -c '...'niż sh -c 'n=$1 ...' _ 127. W tym przypadku nie ma powodu, aby preferować jeden od drugiego, ponieważ oba są idealnie typowym sposobem przekazywania wartości.
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;}

Ta metoda konwertuje liczbę dziesiętną na binarną do 64 bity.

Po wykonaniu powyższej metody w Linqpad - rr = p (-32768); rr.Dump ();

Wynik: 01111111111111111111111111111111111111111111111111000000000000000

Rajesz
źródło
Specyfikacja wymaga „ciągu wejściowego”. Wygląda na to, że ta metoda akceptuje an int.
Poke
0

Java 8, 80 71 bajtów

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

-9 bajtów z powodu reguły w komentarzach. Ujemne dane wejściowe base-10 mogą zwracać dodatnią / bezwzględną wartość base-2 jako dane wyjściowe.

Wyjaśnienie:

Wypróbuj online.

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
Kevin Cruijssen
źródło
0

Kotlin, 82 bytes

{s:String->{var i=s.toInt()
var r=""
(0..15).map{r="${i and 1}$r"
i=i shr 1}
r}()}

Try it online!

JohnWells
źródło
0

Small Basic, 133 bytes

A script that inputs from and outputs to the TextWindow console.

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

Try it at SmallBasic.com Requires Silverlight and thus must be run in IE.

I/O is taken/given from the black console.

-22 bytes thanks to @Neil

Taylor Scott
źródło
Can you not use For i=0To c-1?
Neil
@Neil - I absolutely can. Great catch!
Taylor Scott
0

MATL, 15 17 bytes

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

Try it on MATL Online

TIO

(+2 bytes removing leading 0 for negative numbers, sign bit should be the first bit.)

Output on MATL Online should be read bottom-up (MSB is at the bottom).

The main part is pretty simple: `2&\t = while the value is greater than 0, divide by 2 and accumulate the remainders.

Handling negative numbers and giving them 2's complement representation was the tricky part. In the end I went with the "subtract from 2N" method of getting a number's two's complement. Since we're only required to handle values upto -32768, for negative numbers the code creates 216=65536 with 16W, adds the input to that (eg. 65536 + (-42)), which gives something MATLAB sees as a positive number but represents the input's signed binary representation in 16-bit form.

sundar - Reinstate Monica
źródło