Konwerter binarny na dziesiętny
O ile widzę, nie mamy prostego wyzwania konwersji binarnej na dziesiętną.
Napisz program lub funkcję, która przyjmuje dodatnią liczbę całkowitą binarną i wypisuje swoją wartość dziesiętną.
Nie możesz używać żadnych wbudowanych podstawowych funkcji konwersji. Funkcje od liczb całkowitych do dziesiętnych (np. Funkcja, która zamienia się 101010
w [1, 0, 1, 0, 1, 0]
lub "101010"
) są wyłączone z tej reguły i dlatego są dozwolone.
Zasady:
- Kod musi obsługiwać liczby binarne do najwyższej wartości liczbowej obsługiwanej przez język (domyślnie)
- Możesz wybrać początkowe zera w reprezentacji binarnej
- Dane dziesiętne mogą nie zawierać zer wiodących.
- Formaty wejściowe i wyjściowe są opcjonalne, ale między cyframi nie może być żadnych separatorów.
(1,0,1,0,1,0,1,0)
nie jest poprawnym formatem wejściowym, ale oba są10101010
i(["10101010"])
są.- Musisz przyjąć dane wejściowe w kierunku „normalnym”. nie
1110
jest .14
7
- Musisz przyjąć dane wejściowe w kierunku „normalnym”. nie
Przypadki testowe:
1
1
10
2
101010
42
1101111111010101100101110111001110001000110100110011100000111
2016120520371234567
Wyzwanie to wiąże się z kilkoma innymi wyzwaniami, na przykład tym , tym i tym .
code-golf
base-conversion
binary
Stewie Griffin
źródło
źródło
-1
(32 1's
i64 1's
)round(x)==x
nic ci nie jest :)2.000
przyjmowane jest wyjście dla10
.Odpowiedzi:
Galaretka , 5 bajtów
Wypróbuj online!
Wyjaśnienie
Obsada
D
to monada (funkcja pojedynczego argumentu): cyfry zamieniają się1234
w[1, 2, 3, 4]
.Ḥ
to monada, która podwaja swój pojedynczy argument.+
to diada (funkcja dwóch argumentów), która dodaje lewy i prawy argument.Stamtąd robi się trochę trudniej.
Oto, co dzieje się w czasie analizy
D
,Ḥ
i+
są czytane. Łańcuch wygląda[D, Ḥ, +]
.Kolejne dwa znaki to znaki szybkie , które działają jak operatory Postfix w czasie analizy na linkach (funkcjach), które czytaliśmy do tej pory.
Po
¥
odczytaniu dwa ostatnie łącza są usuwane i zastępowane przez łącze, które działa jak diada utworzona przez ich skomponowanie. Więc teraz wygląda łańcuch[D, dyad(Ḥ+)]
.Kiedy
/
jest czytany, ostatni link (który powinien być diadem) zostaje wysunięty i zastąpiony przez monadę, która składa się za pomocą tej diady (intuicyjnie:f/
pobiera listę, zastępuje ją przecinkamif
i ocenia wynik).Ostatni łańcuch wygląda jak
[D, fold(dyad(Ḥ+))]
dwie monady.Oto, co dzieje się w czasie wykonywania
Dane wejściowe (liczba) są domyślnie wczytywane do wartości roboczej (powiedzmy
101010
).D
jest wykonywany, zastępując wartość roboczą cyframi ([1,0,1,0,1,0]
).fold(dyad(Ḥ+))
jest wykonywana, zastępując wartość roboczą1∗0∗1∗0∗1∗0
, gdzie∗
jest diadaḤ+
.Więc co
x∗y
ocenia?W diadycznej definicji, wartość pracy jest początkowo lewy argument
x
.Ḥ
, podwójna monada, podwaja tę wartość. Wartość robocza jest teraz2x
.+
, plus diada, nie ma właściwego argumentu, więc jest to haczyk : specjalny składniowy wzór, w który wprowadza się odpowiedni argument tej diady+
. Daje2x + y
to końcową wartość roboczą, która jest zwracana.Całe wyrażenie ocenia więc:
źródło
Python 2,
49373130 BajtówTeraz zajmie to liczbę binarną w postaci dziesiętnej, ponieważ Python może obsługiwać dowolnie duże liczby całkowite.
dzięki xnor za zapisanie bajtu :)
Najłatwiejszym sposobem sprawdzenia, jak to działa, jest zapoznanie się z podstawową formułą konwersji wartości binarnych na dziesiętne:
Jest to „standardowy” sposób konwersji. Możesz rozwinąć trzecią linię w następujący sposób:
I to jest właśnie to, co zrobiłem metodą rekurencyjną.
Alternatywne rozwiązania, które miałem:
źródło
n%5
lubn%2
zamiastn%10
.05AB1E , 6 bajtów
Kod:
Dla wyjaśnienia weźmy przykład 101010 . Zaczynamy od cyfry 1 (reprezentowanej przez pierwszą cyfrę). Następnie mamy dwa przypadki:
Tak więc dla przypadku 101010 obliczane są:
Objaśnienie kodu:
Wykorzystuje kodowanie CP-1252 . Wypróbuj online!
źródło
Haskell,
16111 + 57 = 168 bajtów+57 bajty dla flagi kompilacji
-XOverloadedStrings
,-XOverlappingInstances
a-XFlexibleInstances
.Wyzwanie ma pewien uciążliwy format IO , ponieważ w dużej mierze zależy od sposobu wyrażenia typów danych w kodzie źródłowym. Moja pierwsza wersja (16 bajtów), a mianowicie
pobiera listę liczb całkowitych, np.
[1,0,1,0,1,0]
i została uznana za niepoprawną, ponieważ literalne listy Haskella zdarzają się mieć,
między elementami. Listy jako takie nie są zabronione. W mojej nowej wersji używam tej samej funkcji, teraz o nazwief
, ale przeciążam „Cytuj zamknięte sekwencje znaków”. Funkcja nadal pobiera listę liczb całkowitych, jak widać w adnotacji typu[Int] -> Int
, ale listy z liczbami całkowitymi jednocyfrowymi można teraz zapisywać jak"1234"
np.co ocenia na
42
. Pech Haskell, ponieważ natywny format listy nie pasuje do reguł wyzwań. Btw,f [1,0,1,0,1,0]
nadal działa.źródło
(1,0,1,0,1,0,1,0)
nie jest prawidłowym formatem wejściowym, ale oba są10101010
i(["10101010"])
są”. ponadto komentarz sugeruje, że tablica znaków jest dopuszczalna, jeśli w ten sposób interpretowany jest ciąg znaków.10101010
,"10101010"
lub coś podobnego i to działało następnie przedłożenie jest prawidłowy. Możesz nazwać to ciągiem, listą, liczbą całkowitą lub czymkolwiek. Wprowadzanie[1][0][1][0]
lub[1,0,1,0]
jest nieprawidłowe. Zasadniczo powinno być możliwe wybranie gdzieś jednego zera i zer. Czy to jasne?Siatkówka, 15 bajtów
Konwertuje z binarnego na unarny, a następnie z unarnego na dziesiętny.
Wypróbuj online
źródło
PHP, 44 bajty
Mógłbym przysiąc, że widziałem już to pytanie. Ale dobrze.
Odczytuje liczbę od lewej do prawej, przesuwa się w lewo i dodaje bieżący bit.
źródło
JavaScript (ES6),
3331 bajtówEdycja: Krótszy, ale mniej słodki: 2 bajty zapisane dzięki @ETHproductions.
źródło
.map
jest krótszy:s=>[...s].map(c=>+c+r+r,r=0)|r
s=>[...s].map(c=>r+=+c+r,r=0)|r
Labirynt ,
1715 bajtówWypróbuj online!
Labirynt to dwuwymiarowy język oparty na stosach. W labiryncie wykonywanie kodu odbywa się zgodnie ze ścieżką kodu, podobnie jak labirynt ze spacjami działającymi jak ściany i rozpoczynającymi się od lewego górnego znaku spacji. Przepływ kodu jest określony przez znak górnej części stosu. Ponieważ stos zawiera ukryte zera u dołu, pierwsze cztery instrukcje (
-+:+
) nie działają.Pętla zaczynająca się od
,
,
Wciśnij wartość kodu ascii następnego znaku wejściowego do końca stosu lub wciśnij -1, jeśli EOF._48
przesuwa 48 na szczyt stosu-
Pop y, pop x, pushx-y
. Poprzednie instrukcje powodują odjęcie 48 od wartości wejściowej, dając 0 dla „0” i 1 dla „1”.+
Pop y, pop x, pushx+y
.:
Zduplikuj górę stosu+
Ta i poprzednia instrukcja powodują pomnożenie bieżącej wartości przez 2Tak więc okrągła część kodu w efekcie zwielokrotnia bieżącą liczbę przez 2 i dodaje 1 lub 0 w zależności od tego, czy wprowadzono znak 1 czy 0.
Ogon
Jeśli górna część stosu jest ujemna (co oznacza, że znaleziono EOF), kod skręci w lewo na skrzyżowaniu (w kierunku średnika).
)
Pokryj górę stosu, aby uzyskać 2/
Pop y, pop x, push x / y (dzielenie liczb całkowitych). Powoduje to cofnięcie ostatniego*2
z pętli.!
Wyprowadza całkowitą reprezentację góry stosu. W tym momencie program się odwraca, ponieważ trafił w ślepy zaułek, a następnie wychodzi z błędem, ponieważ próbuje podzielić przez zero.Dzięki @Martin Ender za uratowanie mi 2 bajtów (i nauczenie mnie, jak lepiej myśleć w Labiryncie).
źródło
_48-
możesz po prostu zrobić,#%
ale niestety nie widzę, jak to może pomóc w liczeniu bajtów.`)
zamiast;_2
chociaż.#%
. Czy możesz wyjaśnić, jak to działa jako zamiennik_48-
do konwersji z ascii na int. Dzięki za)
wskazówkę. Dokonam tej zmiany.#
jest to po prostu skrót_2
. Chociaż_2%
nie jest to ogólna metoda konwersji ASCII na liczbę całkowitą, działa tutaj, ponieważ interesują Cię tylko pierwsze dwie cyfry jako możliwe dane wejściowe. Alternatywą byłoby_1&
(ponieważ modulo 2 po prostu wyodrębnia najmniej znaczący bit).#%
) do ogólnego skrócenia kodu.Brain-Flak ,
46, 28 bajtówWypróbuj online!
Wiele wielu bajtów zapisanych dzięki @Riley!
Ponieważ atak mózgu nie może przyjmować danych binarnych, dane wejściowe to lista „0” i „1”.
Wyjaśnienie:
źródło
([]){({}[()]<({}<>({}){})><>)}<>
([]){{}({}<>({}){})<>([])}<>
Java,
84794648 bajtówZmieniono na
long
/ 48 bajtów:Czy trochę golfa / 46 bajtów:
Dzięki @Geobits! / 79 bajtów:
84 bajtów:
źródło
s
powinno byćchar[]
. Mam nadzieję, że jest to dozwolone ...Befunge-98, 12 bajtów
Wypróbuj online!
Odczytuje jeden znak na raz z wejścia, konwertuje go na 0 lub 1, przyjmując jego wartość modulo 2 (0 to char (48), 1 to char (49)), a następnie używa zwykłego algorytmu podwajania bieżącej wartości i dodawania nowa cyfra za każdym razem.
Premia: Działa to z dowolnym rodzajem ciągu wejściowego, od jakiegoś czasu próbuję znaleźć jakąś zabawną kombinację wejścia -> wyjścia, ale nie byłem w stanie nic wytworzyć (niestety „odpowiedź” = 46). Czy możesz?
źródło
JavaScript (ES7)
414036 bajtówpobiera ciąg jako dane wejściowe
Ogolono bajt dzięki produktom ETH
źródło
**
jest dziwna, ale przydaje się tutaj dobra robota.1<<b.length
zrobiłby to samo, ale wymagałoby to, aby nawiasy nie były analizowane jako(c*1)<<(b.length+...)
. Myślę, że możesz zapisać bajt, zastępującb[0]
gob+b
( patrz tutaj ).C # 6,
853736 bajtówźródło
05AB1E , 7 bajtów
Wypróbuj online!
Wyjaśnienie
źródło
C, 53
Taki sam jak moja odpowiedź w języku JavaScript
Test Ideone
źródło
v
ic
jako zmienne globalne (choć musisz zmienić nazwęv
, ponieważ jest to już nazwa funkcji) w następujący sposób:w=0;c;v(char*s){while(c=*s++)w+=w+c-48;return w;}
w,c;
ale nie chcę używać globałów, gdy odpowiedź jest funkcją (nawet w golfie)=0
.Perl, 25 bajtów
-3 bajty dzięki @Dom Hastings.
24 bajty kodu + 1 bajt na
-p
flagę.Aby uruchomić:
Objaśnienia:
źródło
Natrętny , 10 bajtów
Zajmuje wejście jako lista 0/1 w linii poleceń:
$ pushy binary.pshy 1,0,1,0,1,0
.Algorytm naprawdę pokazuje piękno posiadania drugiego stosu:
Ta metoda działa, ponieważ stos zostanie podwojony
stack length - n
razy, zanim osiągnie liczbęn
, która jest następnie zrzucana do drugiego stosu na później. Oto jak wygląda proces wprowadzania danych101010
:źródło
Matlab, 30 bajtów
Ostatni przypadek testowy zawiera błędy zaokrąglania (z powodu
double
), więc jeśli potrzebujesz pełnej precyzji:z 47 bajtami.
źródło
@(x)sum(2.^(find(flip(x)-48)-1))
że da poprawny wynik dla wszystkich przypadków dla 32 bajtów.flip
działa jakfliplr
ifx
jest jednowymiarowy.f=@(x)..; f('1111001010')
.Siatkówka , 12 bajtów
Liczba bajtów zakłada kodowanie ISO 8859-1.
Wypróbuj online!
Alternatywne rozwiązanie:
Wyjaśnienie
Prawdopodobnie łatwiej będzie to wyjaśnić na podstawie mojej starej, mniej golfowej wersji, a następnie pokazać, jak ją skróciłem. Kiedyś konwertowałem dane binarne na dziesiętne w następujący sposób:
Jedynym sensownym sposobem skonstruowania liczby dziesiętnej w Retinie jest zliczanie rzeczy (ponieważ Retina ma kilka funkcji, które pozwalają wydrukować liczbę dziesiętną reprezentującą ilość). Tak więc naprawdę jedynym możliwym podejściem jest konwersja binarnego na jednoargumentowy, a następnie policzenie liczby jednoznacznych cyfr. Liczy się ostatni wiersz, więc pierwsze cztery konwertują binarne na jednoargumentowe.
Jak to zrobimy? Ogólnie rzecz biorąc, aby przekonwertować z listy bitów na liczbę całkowitą, inicjalizujemy wynik,
0
a następnie przechodzimy przez bity od najbardziej do najmniej znaczącej, podwajamy wartość, którą już mamy, i dodajemy bieżący bit. Np. Jeśli liczba binarna jest1011
, naprawdę obliczymy:Gdzie zaznaczyłem poszczególne bity dla przejrzystości.
Sztuczka polegająca na robieniu tego pojedynczo polega na tym, że a) podwojenie oznacza po prostu powtórzenie liczby ib) ponieważ liczymy
1
s na końcu, nie musimy nawet rozróżniać0
s i1
s w tym procesie. To stanie się wyraźniejsze za sekundę.To, co robi program, polega na tym, że najpierw dodaje przecinek na początku jako znacznik ilości danych wejściowych, które już przetworzyliśmy:
Po lewej stronie znacznika będziemy mieć wartość, którą kumulujemy (która jest poprawnie zainicjalizowana do jednostkowej reprezentacji zera), a po prawej stronie wartości będzie następny bit do przetworzenia. Teraz stosujemy następujące podstawienie w pętli:
Wystarczy spojrzeć na
,(.)
i i$1,
za każdym razem przesuwa znacznik nieco w prawo. Ale wstawiamy także$`
, czyli wszystko przed znacznikiem, tj. Bieżącą wartość, którą podwajamy. Oto poszczególne kroki przetwarzania danych wejściowych1011
, w których zaznaczyłem wynik wstawiania$`
powyżej każdej linii (dla pierwszego kroku jest pusty):Zobaczysz, że zachowaliśmy i podwoiliśmy zero wraz ze wszystkim innym, ale ponieważ pomijamy je na końcu, nie ma znaczenia, jak często je podwajaliśmy, o ile liczba
1
s poprawny. Jeśli je policzysz, jest11
ich tylko to, czego potrzebujemy.Pozostawia to pytanie, jak zagrać w golfa do 12 bajtów. Najdroższa część 18-bajtowej wersji wymaga użycia znacznika. Celem jest pozbycie się tego. Naprawdę chcemy podwoić każdy prefiks, więc pierwszy pomysł może być następujący:
Problem polega na tym, że te zamiany odbywają się jednocześnie, więc pierwszy bit nie jest podwajany dla każdego bitu, ale jest po prostu kopiowany za każdym razem. Do wprowadzenia
1011
otrzymamy (oznaczenie wstawionego$`
):Nadal musimy rekurencyjnie przetwarzać dane wejściowe, aby podwojony pierwszy prefiks został ponownie podwojony przez drugi i tak dalej. Jednym z pomysłów jest wstawianie znaczników wszędzie i wielokrotne zastępowanie ich przedrostkiem:
Po pierwszym zastąpieniu każdego znacznika prefiksem musimy pamiętać, gdzie był początek danych wejściowych, więc wstawiamy również linie i używamy
%
opcji, aby upewnić się, że następny$`
odbierze tylko najbliższe źródło.To działa, ale wciąż jest za długie (16 bajtów, licząc
1
s na końcu). Co powiesz na to, żeby się odwrócić? Miejsca, w których chcemy wstawić znaczniki, są oznaczone\B
(pozycja między dwiema cyframi). Dlaczego po prostu nie wstawiamy prefiksów w tych pozycjach? To prawie działa, ale różnica polega na tym, że w poprzednim rozwiązaniu faktycznie usuwaliśmy jeden marker w każdej zamianie, i to ważne, aby proces został zakończony. Jednak\B
są to jednak postacie, tylko pozycje, więc nic nie zostanie usunięte. My może jednak zatrzymać\B
od dopasowania, zamiast tego wstawiając znak niecyfrowy w to miejsce. To zamienia granicę niebędącą słowem w granicę słowa, co jest równoważne wcześniejszemu usunięciu znaku znacznika. I tak działa 12-bajtowe rozwiązanie:Dla kompletności, oto poszczególne etapy przetwarzania
1011
, z pustym wierszem po każdym kroku:Ponownie okaże się, że ostatni wynik zawiera dokładnie 11
1
sekund.Czy jako ćwiczenie dla czytelnika możesz zobaczyć, jak dość łatwo generalizuje się to do innych baz (dla kilku dodatkowych bajtów na przyrost w bazie)?
źródło
T-SQL, 202 bajtów
źródło
PHP, 64 bajty
Odwracamy naszą liczbę binarną, dzielimy ją na cyfry składowe i sumujemy na podstawie pozycji.
źródło
Narzędzia Bash + GNU, 29 bajtów
I / O poprzez stdin / stdout.
sed
Wyrażenie dzieli binarny góry do każdej cyfry i buduje wyrażenia RPN dladc
oceny.źródło
PowerShell v2 +, 55 bajtów
Czuje się za długo ...Wydaje się Nie wydaje się, żeby grał w golfa - docenione wskazówki.Wyjaśnienie
źródło
JavaScript (ES6), 32 bajty
Rekursja znów oszczędza dzień! Chociaż parametryzacja wydaje się trochę długa ...
źródło
[...n]
musi być otoczony nawiasami?Mathematica,
271311 bajtówAkceptuje
List
bitów jako wejście (na przykład{1, 0, 1, 1, 0}
- Mathematica jest binarna reprezentacja liczby22
)źródło
Characters
funkcji.IntegerDigits
.D
, który robi to samo, coIntegerDigits
Clojure,
1141056341 bajtówV4: 41 bajtów
-22 bajty dzięki @cliffroot. Ponieważ
digit
jest to znak, można go przekonwertować na kod za pomocąint
, a następnie odjąć 48, aby uzyskać rzeczywistą liczbę. Mapa została również uwzględniona. Nie wiem, dlaczego wydawało się to konieczne.V3: 63 bajty
-42 bajty (!), Zerkając na inne odpowiedzi. Moje „zipowanie” było ewidentnie bardzo naiwne. Zamiast podnieść 2 do potęgi aktualnego miejsca, a następnie pomnożyć go przez bieżącą cyfrę i dodać wynik do akumulatora, wystarczy pomnożyć akumulator przez 2, dodać bieżącą cyfrę, a następnie dodać do akumulatora. Również przekonwertowałem funkcję redukcji na makro, aby trochę się ogolić.
Dzięki @nimi i @Adnan!
Nie golfowany:
V2: 105 bajtów
-9 bajtów poprzez odwrócenie łańcucha, więc nie muszę tworzyć niewygodnego zakresu malejącego.
V1: 114 bajtów
Cóż, na pewno nie wygrywam! W mojej obronie jest to pierwszy program, jaki napisałem, który konwertuje między bazami, więc musiałem nauczyć się, jak to robić. Nie pomaga również, że
Math/pow
zwraca wartość podwójną, która wymaga konwersji iInteger/parseInt
nie przyjmuje znaku, więc cyfra musi zostać owinięta przed przekazaniem.Zipuje łańcuch z indeksem malejącym reprezentującym numer miejsca. Zmniejsza w stosunku do wynikowej listy.
Nie golfowany:
źródło
#(reduce(fn[a b](+(* a 2)(-(int b)48)))0 %)
poprawiona wersja. Przeniesionomap
część kodu bezpośrednio doreduce
, zmieniono metodę analizy liczb całkowitych, wprowadzono funkcję zewnętrzną ze skróconą składnią lambda.int
może być użyty do parsowania !? To zrzuci jak 10 bajtów w każdym wyzwaniu, które tutaj zrobiłem lol.Perl,
211916 + 4 = 20 bajtów-4 bajty dzięki @Dada
Uruchom z
-F -p
(w tym dodatkowe miejsce poF
). Wartości rur do funkcji za pomocąecho -n
Uruchom jako
echo -n "101010" | perl -F -pE '$\+=$_+$\for@F}{'
Wydaje mi się, że to wystarczająco różni się od odpowiedzi @ Dady, że zasługuje na swój własny wpis.
Wyjaśnienie:
Wykorzystuje mój osobisty algorytm do konwersji dwójkowej na dziesiętną. Biorąc pod uwagę liczbę binarną, uruchom akumulator od 0 i przeglądaj jego bity jeden po drugim. Podwój akumulator w każdym bicie, a następnie dodaj sam bit do akumulatora, a skończysz na wartości dziesiętnej. Działa, ponieważ każdy bit zostaje podwojony odpowiednią liczbę razy dla jego pozycji w oparciu o liczbę bitów pozostałych w oryginalnej liczbie binarnej.
źródło
perl -F -pE '$\+=$_+$\for@F}{'
R (32-bit), 64 bajty
Dane wejściowe dla funkcji należy podać jako znak. Podstawowe funkcje R obsługują 32-bitowe liczby całkowite.
Wkład:
Wydajność:
R (64-bit), 74 bajty
Dane wejściowe dla funkcji należy podać jako znak. Paczka
bit64
musi być używany dla 64-bitowych liczb całkowitych.Wkład:
Wydajność:
źródło
el(strsplit(x,""))
zamiaststrsplit(x,split="")[[1]]
zaoszczędzić kilka bajtów.el
funkcji - nie byłem tego świadomy.Dyalog APL , 12 bajtów
⍞
uzyskać ciąg wejściowy⍎¨
zamień każdy znak na liczbę⌽
rewers(
...)/
wstaw następujące funkcje między liczbami++⊢
suma argumentów plus właściwy argumentngn ogolił 2 bajty.
źródło
k, 8 bajtów
Ta sama metoda, co odpowiedź Haskella powyżej.
Przykład:
źródło