Konverter biner ke desimal
Sejauh yang saya lihat, kami tidak memiliki tantangan konversi biner sederhana ke desimal.
Tulis program atau fungsi yang mengambil bilangan bulat biner positif dan mengeluarkan nilai desimalnya.
Anda tidak diperbolehkan menggunakan fungsi konversi basis bawaan apa pun. Fungsi integer-ke-desimal (mis., Fungsi yang berubah 101010
menjadi [1, 0, 1, 0, 1, 0]
atau "101010"
) dikecualikan dari aturan ini dan karenanya diizinkan.
Aturan:
- Kode harus mendukung angka biner hingga nilai numerik tertinggi yang didukung bahasa Anda (secara default)
- Anda dapat memilih untuk memiliki nol di depan dalam representasi biner
- Output desimal mungkin tidak memiliki nol di depan.
- Format input dan output adalah opsional, tetapi tidak ada pemisah antara digit.
(1,0,1,0,1,0,1,0)
bukan format input yang valid, tetapi keduanya10101010
dan(["10101010"])
sedang.- Anda harus mengambil input ke arah "normal".
1110
adalah14
tidak7
.
- Anda harus mengambil input ke arah "normal".
Kasus uji:
1
1
10
2
101010
42
1101111111010101100101110111001110001000110100110011100000111
2016120520371234567
Tantangan ini terkait dengan beberapa tantangan lain, misalnya ini , ini dan ini .
code-golf
base-conversion
binary
Stewie Griffin
sumber
sumber
-1
(32 1's
dan64 1's
)round(x)==x
Anda baik-baik saja :)2.000
diterima untuk10
.Jawaban:
Jelly , 5 byte
Cobalah online!
Penjelasan
Pemeran
D
adalah monad (fungsi argumen tunggal): digit, berubah1234
menjadi[1, 2, 3, 4]
.Ḥ
adalah monad yang menggandakan argumen tunggal.+
adalah angka dua (fungsi dua argumen) yang menambahkan argumen kiri dan kanannya.Dari sana, itu menjadi sedikit rumit.
Inilah yang terjadi pada waktu parse
D
,,Ḥ
dan+
dibaca. Rantai itu terlihat seperti[D, Ḥ, +]
.Dua karakter berikutnya adalah quicks , yang bertindak seperti operator postfix parse-time pada tautan (fungsi) yang telah kita baca sejauh ini.
Ketika
¥
dibaca, dua tautan terakhir akan muncul dan diganti oleh tautan yang bertindak seperti angka dua yang dibentuk dengan menyusunnya. Jadi sekarang rantai itu seperti[D, dyad(Ḥ+)]
.Ketika
/
dibaca, tautan terakhir (yang seharusnya menjadi angka dua) akan muncul dan digantikan oleh monad yang melipat menggunakan angka dua ini (secara intuitif:f/
mengambil daftar, mengganti koma di dalamnya denganf
, dan mengevaluasi hasilnya.)Rantai terakhir terlihat seperti
[D, fold(dyad(Ḥ+))]
, dua monad.Inilah yang terjadi pada saat run time
Input (angka) secara implisit membaca ke dalam nilai kerja (katakanlah,
101010
).D
dieksekusi, mengganti nilai kerja dengan digitnya ([1,0,1,0,1,0]
).fold(dyad(Ḥ+))
dieksekusi, menggantikan nilai kerja dengan1∗0∗1∗0∗1∗0
, di mana∗
angka dua ituḤ+
.Jadi apa yang
x∗y
dievaluasi?Dalam definisi diadik, nilai kerja pada awalnya adalah argumen kiri
x
,.Ḥ
, Yang ganda monad, ganda nilai ini. Nilai kerja sekarang2x
.+
, ditambah angka dua, tidak memiliki argumen yang benar, jadi ini adalah sebuah kait : pola sintaksis khusus di mana argumen yang tepat dari angka dua ini akan disuntikkan ke+
. Ini menghasilkan2x + y
sebagai nilai kerja akhir, yang dikembalikan.Jadi seluruh ekspresi dievaluasi menjadi:
sumber
Python 2,
49373130 BytesSekarang ini akan mengambil angka biner dalam representasi desimal, karena Python dapat menangani bilangan bulat besar yang sewenang-wenang.
terima kasih kepada xnor untuk menyimpan byte :)
Cara termudah untuk melihat bagaimana ini bekerja adalah dengan melihat rumus dasar untuk mengubah biner menjadi desimal:
Ini adalah cara konversi yang 'standar'. Anda dapat memperluas baris ketiga seperti:
Dan pada dasarnya inilah yang dilakukan metode rekursif yang saya lakukan.
Solusi alternatif yang saya miliki:
sumber
n%5
ataun%2
bukannyan%10
.05AB1E , 6 byte
Kode:
Untuk penjelasannya, mari kita ambil contoh 101010 . Kita mulai dengan angka 1 (yang diwakili oleh digit pertama). Setelah itu, kami memiliki dua kasus:
Jadi untuk kasus 101010 , berikut ini dihitung:
Penjelasan kode:
Menggunakan pengkodean CP-1252 . Cobalah online!
sumber
Haskell,
16111 + 57 = 168 byte+57 byte untuk flag kompilasi
-XOverloadedStrings
,-XOverlappingInstances
dan-XFlexibleInstances
.Tantangannya memiliki beberapa format IO yang rumit , karena sangat tergantung pada bagaimana tipe data diekspresikan dalam kode sumber. Versi pertama saya (16 byte), yaitu
mengambil daftar bilangan bulat, misalnya
[1,0,1,0,1,0]
dan dinyatakan tidak valid karena daftar Haskell literal terjadi di,
antara elemen-elemen. Daftar per se tidak dilarang. Dalam versi baru saya, saya menggunakan fungsi yang sama, sekarang dinamaif
, tetapi saya membebani "Kutipan urutan karakter terlampir". Fungsi masih mengambil daftar bilangan bulat seperti yang Anda lihat dalam anotasi jenis[Int] -> Int
, tetapi daftar dengan bilangan bulat tunggal sekarang dapat ditulis seperti"1234"
, misalnyayang dievaluasi menjadi
42
. Sial, Haskell, karena format daftar asli tidak sesuai dengan aturan tantangan. Btw,f [1,0,1,0,1,0]
masih berfungsi.sumber
(1,0,1,0,1,0,1,0)
bukan format input yang valid, tetapi keduanya10101010
dan(["10101010"])
sedang." lebih jauh lagi sebuah komentar menunjukkan array karakter dapat diterima jika itu adalah bagaimana input string ditafsirkan.10101010
,"10101010"
atau sesuatu yang serupa dan membuatnya berfungsi maka pengajuan tersebut valid. Anda dapat menyebutnya string, daftar, integer atau apa pun. Memasukkan[1][0][1][0]
atau[1,0,1,0]
tidak ok. Pada dasarnya, itu mungkin untuk hanya menekan sekelompok yang dan nol berturut-turut di suatu tempat. Apakah ini jelas?Retina, 15 byte
Mengubah dari biner ke unary, lalu unary ke desimal.
Cobalah online
sumber
PHP, 44 byte
Saya bersumpah bahwa saya pernah melihat pertanyaan itu sebelumnya. Tapi baiklah.
Membaca angka dari kiri ke kanan, bergeser ke kiri dan menambahkan bit saat ini.
sumber
JavaScript (ES6),
3331 byteSunting: Lebih pendek tapi kurang manis: 2 byte disimpan berkat @ETHproduksi.
sumber
.map
lebih pendek:s=>[...s].map(c=>+c+r+r,r=0)|r
s=>[...s].map(c=>r+=+c+r,r=0)|r
Labirin ,
1715 byteCobalah online!
Labyrinth adalah bahasa dua dimensi, berbasis stack. Di labirin, eksekusi kode mengikuti jalur kode seperti labirin dengan spasi yang bertindak sebagai dinding dan dimulai dengan karakter non-spasi paling kiri. Alur kode ditentukan oleh tanda bagian atas tumpukan. Karena tumpukan memiliki nol tersirat di bagian bawah, empat instruksi pertama (
-+:+
) tidak berpengaruh.Loop dimulai pada
,
,
Dorong nilai kode ascii dari karakter input berikutnya ke stop stack, atau tekan -1 jika EOF._48
mendorong 48 ke atas tumpukan-
Pop y, pop x, pushx-y
. Instruksi sebelumnya memiliki efek mengurangi 48 dari input yang menghasilkan 0 untuk "0" dan 1 untuk "1".+
Pop y, pop x, pushx+y
.:
Gandakan bagian atas tumpukan+
Instruksi ini dan sebelumnya memiliki efek mengalikan nilai saat ini dengan 2Jadi bagian melingkar dari kode, pada dasarnya, mengalikan angka saat ini dengan 2 dan menambahkan angka 1 atau 0 tergantung pada apakah karakter 1 atau 0 dimasukkan.
Ekor
Jika bagian atas tumpukan negatif (artinya EOF ditemukan), kode akan belok kiri di persimpangan (menuju tanda titik koma).
)
Tambahkan bagian atas tumpukan untuk mendapatkan 2/
Pop y, pop x, push x / y (pembagian integer). Ini memiliki efek membatalkan yang terakhir*2
dari loop.!
Keluarkan representasi integer dari bagian atas tumpukan. Pada titik ini program berbalik karena menemui jalan buntu dan kemudian keluar dengan kesalahan karena mencoba untuk membaginya dengan nol.Terima kasih kepada @Martin Ender karena telah menyelamatkan saya 2 byte (dan mengajari saya cara berpikir yang lebih baik di Labyrinth).
sumber
_48-
Anda bisa melakukannya#%
tetapi sayangnya saya tidak melihat bagaimana hal itu dapat membantu dengan jumlah byte.`)
sebagai gantinya;_2
.#%
. Bisakah Anda menjelaskan cara kerjanya sebagai pengganti untuk_48-
mengonversi dari ascii ke int. Terima kasih atas)
tipnya. Saya akan melakukan perubahan itu.#
hanya kependekan_2
. Meskipun_2%
bukan metode konversi umum untuk ASCII untuk integer, ini berfungsi di sini karena Anda hanya tertarik pada dua digit pertama sebagai input yang mungkin. Alternatifnya adalah_1&
(karena modulo 2 hanya mengekstrak bit yang paling tidak signifikan).#%
) untuk mempersingkat kode secara keseluruhan.Brain-Flak ,
46, 28 byteCobalah online!
Banyak byte yang disimpan berkat @Riley!
Karena brain-flak tidak dapat mengambil input biner, input adalah daftar '0 dan' 1.
Penjelasan:
sumber
([]){({}[()]<({}<>({}){})><>)}<>
([]){{}({}<>({}){})<>([])}<>
Java,
84794648 byteDiubah menjadi
long
/ 48 byte:Melakukan beberapa golf / 46 byte:
Terima kasih kepada @Geobits! / 79 byte:
84 byte:
sumber
s
seharusnyachar[]
. Saya harap itu diizinkan ...Befunge-98, 12 byte
Cobalah online!
Membaca satu karakter sekaligus dari input, mengubahnya menjadi 0 atau 1 dengan mengambil nilainya modulo 2 (0 adalah karakter (48), 1 adalah karakter (49)), kemudian menggunakan algoritma biasa menggandakan nilai saat ini dan menambahkan digit baru setiap kali.
Bonus: Ini berfungsi dengan segala jenis string input, saya sudah mencoba beberapa saat sekarang untuk menemukan kombinasi input-> output yang lucu, tetapi saya tidak dapat menghasilkan apa-apa (sayangnya, "jawaban" = 46). Bisakah kamu?
sumber
Javascript (ES7)
414036 bytemengambil string sebagai input
Mencukur satu byte berkat produk ETH
sumber
**
aneh, tapi pekerjaan yang bagus menggunakannya di sini.1<<b.length
akan melakukan hal yang sama, tetapi akan membutuhkan tanda kurung agar tidak diuraikan sebagai(c*1)<<(b.length+...)
. Saya pikir Anda dapat menyimpan byte dengan menggantinyab[0]
denganb+b
( lihat di sini ).C # 6,
853736 bytesumber
05AB1E , 7 byte
Cobalah online!
Penjelasan
sumber
C, 53
Sama seperti jawaban javascript saya
Ide Tes
sumber
v
danc
sebagai variabel global (meskipun Anda harus mengubah namav
, karena sudah menjadi nama fungsi) seperti ini:w=0;c;v(char*s){while(c=*s++)w+=w+c-48;return w;}
w,c;
tapi saya tidak ingin menggunakan global ketika jawabannya adalah fungsi (bahkan dalam kode-golf)=0
.Perl, 25 byte
-3 byte terima kasih kepada @Dom Hastings.
24 byte kode + 1 byte untuk
-p
flag.Untuk menjalankannya:
Penjelasan:
sumber
Pushy , 10 byte
Mengambil input sebagai daftar 0/1 pada baris perintah:
$ pushy binary.pshy 1,0,1,0,1,0
.Algoritma benar-benar menunjukkan keindahan memiliki tumpukan kedua:
Metode ini berfungsi karena tumpukan akan digandakan
stack length - n
kali sebelum mencapai angkan
, yang kemudian dibuang ke tumpukan kedua untuk nanti. Beginilah prosesnya untuk input101010
:sumber
Matlab, 30 Bytes
Kasing uji terakhir memiliki kesalahan pembulatan (karena
double
), jadi jika Anda membutuhkan presisi penuh:dengan 47 Bytes.
sumber
@(x)sum(2.^(find(flip(x)-48)-1))
akan memberikan hasil yang benar untuk semua kasus selama 32 byte.flip
bekerja sepertifliplr
jikax
satu dimensi.f=@(x)..; f('1111001010')
.Retina , 12 byte
Hitungan byte mengasumsikan penyandian ISO 8859-1.
Cobalah online!
Solusi alternatif:
Penjelasan
Ini mungkin akan lebih mudah dijelaskan berdasarkan versi saya yang lama, kurang golf, dan kemudian menunjukkan bagaimana saya mempersingkatnya. Saya dulu mengonversi biner menjadi desimal seperti ini:
Satu-satunya cara yang masuk akal untuk membangun angka desimal di Retina adalah dengan menghitung banyak hal (karena Retina memiliki beberapa fitur yang memungkinkannya mencetak angka desimal yang mewakili jumlah). Jadi sebenarnya satu-satunya pendekatan yang mungkin adalah mengubah biner menjadi unary, dan kemudian menghitung jumlah digit unary. Baris terakhir menghitung, jadi yang pertama mengkonversi biner ke unary.
Bagaimana kita melakukannya? Secara umum, untuk mengkonversi dari daftar bit ke integer, kami menginisialisasi hasilnya
0
dan kemudian pergi melalui bit dari yang paling signifikan, menggandakan nilai yang sudah kami miliki dan menambahkan bit saat ini. Misalnya, jika angka binernya adalah1011
, kami akan menghitung:Di mana saya telah menandai bit individu untuk kejelasan.
Trik untuk melakukan ini di unary adalah a) bahwa menggandakan berarti mengulangi angka dan b) karena kita menghitung
1
s pada akhirnya, kita bahkan tidak perlu membedakan antara0
s dan1
s dalam proses. Ini akan menjadi lebih jelas dalam sedetik.Apa yang dilakukan oleh program adalah bahwa ia pertama kali menambahkan koma ke awal sebagai penanda untuk berapa banyak input yang sudah kami proses:
Di sebelah kiri marker, kita akan memiliki nilai yang kita akumulasikan (yang diinisialisasi dengan benar ke representasi nol unary), dan kanan nilai akan menjadi bit berikutnya untuk diproses. Sekarang kami menerapkan substitusi berikut dalam satu lingkaran:
Hanya dengan melihat
,(.)
dan$1,
, ini menggerakkan marker sedikit ke kanan setiap kali. Tapi kami juga menyisipkan$`
, yang merupakan segalanya di depan marker, yaitu nilai saat ini, yang kami gandakan. Berikut adalah langkah-langkah individual saat memproses input1011
, di mana saya telah menandai hasil dari menyisipkan di$`
atas setiap baris (kosong untuk langkah pertama):Anda akan melihat bahwa kami telah mempertahankan dan menggandakan nol bersama dengan yang lainnya, tetapi karena kami mengabaikannya pada akhirnya, tidak masalah seberapa sering kami menggandakannya, selama jumlah
1
s adalah benar. Jika Anda menghitungnya, ada beberapa11
, hanya yang kita butuhkan.Sehingga menyisakan pertanyaan bagaimana cara memainkan golf ini hingga 12 byte. Bagian termahal dari versi 18-byte adalah harus menggunakan marker. Tujuannya adalah untuk menyingkirkan itu. Kami benar-benar ingin menggandakan awalan setiap bit, jadi ide pertama mungkin ini:
Masalahnya adalah bahwa pergantian ini terjadi secara bersamaan, jadi bit pertama tidak menjadi dua kali lipat untuk setiap bit, tetapi hanya akan disalin sekali setiap kali. Untuk input yang
1011
akan kami dapatkan (menandai yang dimasukkan$`
):Kita masih perlu memproses input secara rekursif sehingga awalan pertama yang digandakan digandakan lagi oleh yang kedua dan seterusnya. Satu ide adalah menyisipkan spidol di mana-mana dan berulang kali menggantinya dengan awalan:
Setelah mengganti setiap penanda dengan awalan untuk pertama kalinya, kita perlu mengingat di mana awal input itu, jadi kami juga memasukkan umpan baris dan menggunakan
%
opsi untuk memastikan bahwa berikutnya$`
hanya mengambil hal-hal yang sesuai dengan umpan baris terdekat.Ini berfungsi, tetapi masih terlalu lama (16 byte saat menghitung
1
s di akhir). Bagaimana kalau kita membalikkan keadaan? Tempat-tempat di mana kita ingin menyisipkan marker diidentifikasi oleh\B
(posisi di antara dua digit). Mengapa kita tidak memasukkan saja awalan ke posisi itu? Ini hampir berhasil, tetapi perbedaannya adalah bahwa dalam solusi sebelumnya, kami benar-benar menghapus satu penanda di setiap substitusi, dan itu penting untuk membuat proses berakhir. Namun,\B
bukan karakter tetapi hanya posisi, jadi tidak ada yang dihapus. Namun kita dapat menghentikannya\B
dari mencocokkan dengan memasukkan karakter non-digit ke tempat ini. Itu mengubah batas non-kata menjadi batas kata, yang setara dengan menghapus karakter penanda sebelumnya. Dan itulah yang dilakukan solusi 12-byte:Hanya untuk kelengkapan, berikut adalah langkah-langkah pemrosesan
1011
, dengan baris kosong setelah setiap langkah:Sekali lagi, Anda akan menemukan bahwa hasil terakhir mengandung tepat 11
1
detik.Sebagai latihan untuk pembaca, dapatkah Anda melihat bagaimana ini secara umum dengan mudah ke pangkalan lain (untuk beberapa byte tambahan per kenaikan di pangkalan)?
sumber
T-SQL, 202 Bytes
sumber
PHP, 64 byte
Kami membalikkan angka biner kami, membaginya menjadi digit komponennya, dan menjumlahkannya berdasarkan posisi.
sumber
Utilitas Bash + GNU, 29 byte
I / O via stdin / stdout.
The
sed
ekspresi membagi up biner ke setiap digit dan membangun ekspresi RPN untukdc
mengevaluasi.sumber
PowerShell v2 +, 55 byte
Terasa terlalu lama ...Sepertinya tidak bisa mengurangi golf - tips dihargai.Penjelasan
sumber
JavaScript (ES6), 32 byte
Rekursi menghemat hari lagi! Meskipun parameterisasi tampaknya agak panjang ...
sumber
[...n]
perlu dikelilingi dalam tanda kurung?Mathematica,
271311 byteMenerima
List
bit sebagai input (mis.{1, 0, 1, 1, 0}
- Representasi biner dari angka dari Mathematica22
)sumber
Characters
fungsi.IntegerDigits
di tempat pertama.D
, yang melakukan hal yang samaIntegerDigits
Clojure,
1141056341 byteV4: 41 byte
-22 byte berkat @cliffroot. Karena
digit
karakter, dapat dikonversikan ke kode melaluiint
, kemudian memiliki 48 dikurangi dari itu untuk mendapatkan angka aktual. Peta juga diperhitungkan. Saya tidak tahu mengapa itu perlu.V3: 63 byte
-42 byte (!) Dengan mengintip jawaban lain. "Ritsleting" saya ternyata sangat naif. Alih-alih menaikkan 2 ke kekuatan tempat saat ini, lalu mengalikannya dengan digit saat ini dan menambahkan hasilnya ke akumulator, itu hanya mengalikan akumulator dengan 2, menambahkan pada digit saat ini, kemudian menambahkannya ke akumulator. Juga mengonversi fungsi pengurang menjadi makro untuk mengurangi sedikit.
Terima kasih kepada @nimi, dan @Adnan!
Tidak Disatukan:
V2: 105 byte
-9 byte dengan membalikkan string jadi saya tidak perlu membuat rentang turun yang canggung.
V1: 114 byte
Yah, aku tentu saja tidak menang! Dalam pembelaan saya, ini adalah program pertama yang pernah saya tulis yang mengkonversi antara pangkalan, jadi saya harus belajar bagaimana melakukannya. Itu juga tidak membantu yang
Math/pow
mengembalikan dua kali lipat yang memerlukan konversi dari, danInteger/parseInt
tidak menerima karakter, sehingga digit harus dibungkus sebelum lewat.Ritsleting string dengan indeks turun yang mewakili nomor tempat. Mengurangi daftar yang dihasilkan.
Tidak Disatukan:
sumber
#(reduce(fn[a b](+(* a 2)(-(int b)48)))0 %)
versi yang ditingkatkan. Memindahkanmap
bagian kode langsung kereduce
, mengubah metode parsing integer, membuat fungsi eksternal dengan sintaks steno lambda.int
bisa digunakan untuk mengurai !? Itu akan mengetuk seperti 10 byte dalam setiap tantangan yang saya lakukan di sini lol.Perl,
211916 + 4 = 20 byte-4 byte terima kasih kepada @Dada
Jalankan dengan
-F -p
(termasuk ruang ekstra setelahF
). Nilai pipa ke fungsi menggunakanecho -n
Jalankan sebagai
echo -n "101010" | perl -F -pE '$\+=$_+$\for@F}{'
Saya merasa ini cukup berbeda dari jawaban @ Dada yang pantas masuknya sendiri.
Penjelasan:
Ini menggunakan algoritme pilihan pribadi saya untuk konversi biner ke desimal. Diberi nomor biner, mulai akumulator Anda pada 0, dan lalui bitnya satu per satu. Gandakan akumulator setiap bit, lalu tambahkan bit itu sendiri ke akumulator Anda, dan Anda berakhir dengan nilai desimal. Ini bekerja karena setiap bit akhirnya menjadi dua kali lipat jumlah yang tepat untuk posisinya berdasarkan berapa banyak bit yang tersisa di angka biner asli.
sumber
perl -F -pE '$\+=$_+$\for@F}{'
R (32-bit), 64 Bytes
Input untuk fungsi harus diberikan sebagai karakter. Fungsi dasar R mendukung bilangan bulat 32-bit.
Memasukkan:
Keluaran:
R (64-bit), 74 Bytes
Input untuk fungsi harus diberikan sebagai karakter. Paket
bit64
harus digunakan untuk integer 64-bit.Memasukkan:
Keluaran:
sumber
el(strsplit(x,""))
alih-alihstrsplit(x,split="")[[1]]
menyimpan beberapa byte.el
fungsi - saya tidak menyadarinya.Dyalog APL , 12 byte
⍞
dapatkan input string⍎¨
konversi setiap karakter ke angka⌽
membalikkan(
...)/
masukkan fungsi berikut di antara angka-angka++⊢
jumlah argumen ditambah argumen yang benarngn mencukur 2 byte.
sumber
k, 8 byte
Metode yang sama dengan jawaban Haskell di atas.
Contoh:
sumber