Sederhanakan biner

20

Tantangan

Diberi nomor biner sebagai input melalui cara apa pun, "sederhanakan" nomor tersebut menggunakan program lengkap atau fungsi.

Memasukkan

[binary]
  • binary adalah angka dalam biner yang lebih dari 0.

Keluaran

Ambil input, konversikan ke basis 10 tanpa menggunakan builtin, maka jika angka itu hanya berisi 1s dan 0s, ubah menjadi basis 10 seolah-olah itu nomor biner lain. Ulangi proses ini hingga angka tersebut tidak dapat dibaca dalam biner dan tampilkan angka itu.

Informasi lainnya

  • Jika inputnya 1, cukup output 1. Program Anda seharusnya tidak terus menyederhanakan 1.

  • Ini kode golf, jadi jawaban tersingkat dalam byte pada hari Selasa (17 November) menang.

  • Jika ada yang membingungkan, tinggalkan komentar yang menentukan apa yang perlu saya jelaskan dan saya akan mengeditnya.

  • Dibangun untuk konversi basis tidak diperbolehkan.

Contohnya

     Input | Output

         1 | 1
      1010 | 2
      1011 | 3
   1100100 | 4
   1100101 | 5
1111110011 | 3
The_Basset_Hound
sumber
4
Bisa menggunakan beberapa test case.
isaacg
Apakah inputnya string ASCII, atau sebenarnya 1 dan 0?
Tom Carpenter
@TomCarpenter 1s dan 0s.
The_Basset_Hound
@isaacg Menambahkan cara untuk mendapatkan 1-5 sebagai output.
The_Basset_Hound
Apakah fungsi yang mengubah string ke basis yang diberikan diizinkan?
isaacg

Jawaban:

14

Pyth, 20 16 byte

u?-GTG`u+yNsTG0z

4 byte berkat Jakube

Setengah dari kode ( u+yNsTG0) hanyalah kode konversi dasar.

Test Suite

u?-GTG`u+yNsTG0z
                    z = input() (The string of 1s and 0s)
                    T = 10
u              z    Apply until the value stops changing, starting with z
                    G is the current value, a string of 0s and 1s.
 ?-GT               If G - T, e.g., G with the digits 1 and 0 removed is not empty,
     G              Return G, to end the iteration.
       u     G0     Else, reduce over G with initial value 0.
         yN         Double the running total
        +  sT       and add the next digit, cast to an int.
      `             Convert to string.

Input 1ditangani oleh fakta bahwa upemberitahuan nilainya telah berhenti berubah.

isaacg
sumber
4
Selamat, kamu mengalahkan Dennis! Untuk saat ini ...
Conor O'Brien
9
@ CᴏɴᴏʀO'Bʀɪᴇɴ Rahasianya adalah Pyth.
isaacg
8

CJam, 24 23 byte

q{:~{1$++}*s__,(As*-!}g

Cobalah online di juru bahasa CJam .

Bagaimana itu bekerja

q                        Read all input.
 {                   }g  Do:
  :~                       Evaluate each character. Maps '0' -> 0 and '1' -> 1.
    {    }*                Fold; for each integer but the first:
     1$                      Copy the second-topmost integer.
       ++                    Add all three integers on the stack.
           s__             Cast to string and push two copies.
              ,(           Calculate string length and subtract 1.
                As         Push the string "10".
                  *        Repeat the string length-1 times.
                   -       Remove its elements from the string representation
                           of the integer.
                    !      Apply logical NOT.
                         If `!' pushed 1, repeat the loop.
Dennis
sumber
Apakah Anda harus mengulang kali "10"string length-1, atau bisakah Anda melewati penurunan?
DLosc
Mengurangkan 1 dari panjang berubah "10"menjadi ""jika bilangan bulat memiliki satu digit. Ini memastikan kode tidak masuk ke loop tak terbatas.
Dennis
2
Menarik, kapten. }: ^ |
DLosc
7

Pip, 28 27 byte

Ta=1|aRMta:$+(^a)*2**RV,#aa

Mengambil input sebagai argumen baris perintah. Kami ingin mengulang hingga a=1atau amemuat beberapa karakter selain 0 dan 1. Kondisi terakhir ini diuji dengan RMmemasukkan semua karakter dalam t=10 dari a. Jika ada yang tersisa, kondisinya benar.

Di dalam loop, konversi berfungsi sebagai berikut:

a:$+(^a)*2**RV,#a

              ,#a  range(len(a))
            RV     reversed
         2**       2 to the power of each element
    (^a)*          multiplied item-wise with each digit in split(a)
  $+               Sum
a:                 and assign back to a

Puting a pada akhirnya mencetak secara otomatis.

Solusi rekursif dalam 28 byte:

a<2|aRMt?a(f$+(^a)*2**RV,#a)
DLosc
sumber
6

Python 2, 52

f=lambda n:n>1<'2'>max(`n`)and f(n%10+2*f(n/10))or n

Lebih mudah untuk menganggap ini sebagai dua fungsi rekursif:

g=lambda n:n and n%10+2*g(n/10)
f=lambda n:n>1<'2'>max(`n`)and f(g(n))or n

Fungsi gmengubah nilai desimal ke biner, dan fungsi fberlaku gberulang kali selama argumennya dibuat dari angka 0 dan 1 ( '2'>max(`n`)) dan tidak 1. Kode golf memecahnya menjadi satu fungsi dengan menyisipkan definisi g(n)untuk f(n), menggantikan panggilan rekursif gdengan f. Kasus dasar n=0dari gsecara otomatis ditangani oleh cek n>1.

Tidak
sumber
Bagus :) Satu-satunya masalah adalah bahwa masalah yang biasa terjadi - sial Ldari repr...
Sp3000
4

Prolog, 220 212 byte

:-use_module(library(clpfd)).
x(B,N):-reverse(B,C),foldl(y,C,0-0,_-N).
y(B,J-M,I-N):-B in 0..1,N#=M+B*2^J,I#=J+1.
b(N,I):-N>47,N<50,I is(N-48).
p(N):-N>1,number_codes(N,L),maplist(b,L,Y),x(Y,B),p(B);write(N).

Penjelasan
p adalah fungsi utama dan melakukan langkah-langkah berikut (dengan bantuan dari b, x, y):

  • memeriksa apakah nomor saat ini lebih besar dari 1
  • mengkonversi integer ke daftar representasi digit ascii
  • memeriksa apakah semua angka 0 atau 1
  • mengkonversi daftar ascii ke daftar integer biner
  • mengubah daftar bilangan bulat biner ke angka desimal
  • berulang
  • mencetak ketika predikat gagal.

Sunting: Disimpan 8 byte dengan menyatukan p-klausa dengan OR.

Emigna
sumber
3

Mathematica 107 106

Dengan byte yang disimpan oleh DLosc.

j@d_:=(p=0;v=IntegerDigits@d;
Which[d<2,1,Complement[v,{0,1}]=={},j@Fold[#+#2 2^p++&,0,Reverse@v],1<2,d])

Pecah input menjadi digit-digitnya. Jika inputnya 1, output 1.

Jika input adalah angka yang terdiri dari 0 dan 1, konversikan ke desimal dan jalankan kembali.

Jika tidak, kembalikan input.


j[1]

1


j[11010001]

209


j[1111110001]

1009


j[1111110011]

3

Langkah pertama menghasilkan 1011 yang pada gilirannya menghasilkan 3.


Di sini kami menguji mulai dengan 1011.

j[1011]

3

DavidC
sumber
3

Javascript, 132 , 123 byte

Yah, itu bukan jawaban terbaik, tapi ..

FYI, jika input yang tidak valid diberikan, ini akan menampilkan hal yang sama kepada pengguna.

function c(x){while(x!=0&&!/[2-9]/.test(x)){for(i=r=0;x;i++)r+=x%10*Math.pow(2,i),x=parseInt(x/10);x=r}alert(x)}c(prompt())

Pengembang Pembelajaran
sumber
1
Anda bisa menyimpan 19 byte dengan menggunakan foralih-alih whiledan menetapkan nilai langsung dalam pernyataan (ini juga mengurangi beberapa {}), membuang beberapa ;, menggunakan deskripsi fungsi ES6, increment iinline. Ini akan terlihat seperti ini: c=x=>{for(r=0;x&&!/[2-9]/.test(x);x=r)for(i=0;x>0;r+=x%10*Math.pow(2,i++),x=parseInt(x/10));alert(x)};c(prompt()).
masukkan nama pengguna di sini
1
114:function c(x){while(x^0&&!/[2-9]/.test(x)){for(i=r=0;x;i++)r+=x%10*Math.pow(2,i),x=0|x/10;x=r}alert(x)}c(prompt())
Mama Fun Roll
@insertusernamehere, terima kasih atas sarannya, tapi saya tidak mengerti c=x=>awalnya, tidak bekerja di Chrome atau konsol Firefox. :( @ ן nɟuɐɯɹɐ ן oɯ, tidak bisa membungkus kepala saya dengan kondisi XOR dan x=0|x/10‌alih - alih parseInt, saya sudah memasukkan sisa perubahan. Terima kasih ..
LearningDeveloper
@ GauthamPJ Maaf, entah bagaimana kode rusak saat menyalin dan berisi karakter yang tidak patut. Berikut versi yang benar: c=x=>{for(r=0;x!=0&&!/[2-9]/.test(x);x=r)for(i=r=0;x;)r+=x%10*Math.pow(2,i++),x=parseInt(x/10);alert(x)};c(prompt()). Ini pasti berjalan di Firefox 42, coba biola ini . Perhatikan bahwa ini versi yang lebih golf dan juga kode asli Anda tidak berfungsi 1dan akan mengalami loop tanpa akhir. c=x=>seperti function c(x){}melihat " Fungsi panah ".
masukkan nama pengguna di sini
2

JavaScript ES6, 52

Sebagai fungsi. Argumen fungsi harus berupa string angka biner atau angka yang representasi desimalnya hanya berisi 1 dan 0.

Tes menjalankan cuplikan di bawah ini di peramban yang mendukung EcmaScript 6 - menerapkan fungsi panah, string templat, dan operator spread (saya menggunakan Firefox)

f=s=>s<2|[...s+''].some(c=>(n+=+c+n,c>1),n=0)?s:f(n)

// To test
console.log=(...x)=>O.innerHTML+=x+'\n';

// Basic test cases
;[[1,1],[1010,2],[1011,3],[1100100,4],[1100101,5],[1111110011,3]]
.forEach(t=>console.log(t[0]+' -> '+f(t[0])+' expected '+t[1]))

function longtest() {
  var o=[],i;
  for (i=1;i<1e6;i++)
    b=i.toString(2),v=f(b),v!=i?o.push(b+' '+v):0;
  O.innerHTML=o.join`\n`
}
Click to run the long test <button onclick="longtest()">go</button>
<pre id=O></pre>

edc65
sumber
1
Sangat menyukai n+=+c+nkonversi biner. Sangat elegan ...
nderscore
2

Mathematica, 62 59 55 48 byte

Disimpan 7 byte berkat Martin Büttner.

#//.a_/;Max[b=IntegerDigits@a]<2:>Fold[#+##&,b]&
alephalpha
sumber
1

Javascript (ES7) 87 80 78 77 74 byte

Cuplikan cuplikan untuk mendukung browser (saat ini hanya Firefox malam mendukung operator eksponensial)

f=x=>[...x].reverse(i=y=j=0).map(z=>(j|=z,y+=z*2**i++))&&j<2&y>1?f(y+[]):x
<input type="text" id="x" value="1111110011"><button onclick="o.innerHTML=f(x.value)">Run</button><div id="o"></div>

f=x=>
[...x].reverse(i=y=j=0) // reverse string as array, initialize vars
.map(z=>( // iterate over the all chatacters
    j|=z, // keep track of whether a digit higher than 1 is encountered
    y+=z*2**i++ // build decimal result from binary
))&&
j<2&y>1? // if we encountered only 1's and 0's and result > 1
    f(y+[]) // then call recursively and cast to a string
    :x // else return x

Javascript (ES6) 81 byte

Demo cuplikan untuk mendukung browser

f=x=>[...x].reverse(i=y=j=0).map(z=>y+=z*Math.pow(2,i++,j|=z))&&j<2&y>1?f(y+[]):x
<input type="text" id="x" value="1111110011"><button onclick="o.innerHTML=f(x.value)">Run</button><div id="o"></div>

nderscore
sumber
1

𝔼𝕊𝕄𝕚𝕟, 37 karakter / 54 byte

↺;ï>1⅋(⬯+ï)ĉ/^[01]+$⌿);)ï=+('ᶀ'+ï);ôï

Try it here (Firefox only).

Tidak yakin apakah +operator dianggap sebagai built-in untuk konversi biner ...

Mama Fun Roll
sumber
1

Perl 6 , 67 byte

get,{$_=0;for $^a.comb {$_+<=1;$_+=$^b};$_}...1|/<-[01]>/;say $_//1
Brad Gilbert b2gills
sumber
1

PHP, 210 204 byte

Ini pertama kalinya saya memposting di sini, jadi harap kalian akan menyukainya! Bahkan jika itu jelas bukan cara terbaik untuk menulisnya, aku masih senang memamerkannya di sini!

Kode

<?function j($a){$c=0;if($a==1){return 1;}else{if(preg_match("#^[01]+$#",$a)){$b=strlen($a);$a=str_split($a);foreach($a as$d){$c+=($d==0?0:2**($b-1));$b--;}return j($c);}else{return$a;}}}echo j($_GET[0]);

Saya telah membuat fungsi rekursif "j" yang pertama-tama akan memeriksa apakah input sama dengan 1. Jika demikian, fungsi mengembalikan 1 seperti yang diharapkan, jika tidak maka akan membagi angka dalam array untuk menghitung nilai desimal, tetapi hanya jika angkanya adalah biner. Jika tidak, itu akan mengembalikan nomornya apa adanya.

Kode tidak dikunci

<?
function j($a) {
  $c = 0;
  if ($a == 1) {
    return 1;
  }
  else {
    if (preg_match("#^[01]+$#", $a) {
      $b = strlen($a);
      $a = str_split($a);
      foreach ($a as $d) {
        $c += ($d == 0 ? 0 : 2 ** ($b - 1));
        $b--;
      }
      return j($c);
    }
    else {
      return $a;
    }
  }
}
echo j($_GET[0]);

Saya telah menggunakan pernyataan "foreach" alih-alih inisial "untuk" saya, memungkinkan saya memperoleh 6 byte tetapi saya cukup yakin ada banyak hal yang harus dilakukan.

Vincent Douay
sumber
1

PHP, 114 112 byte

juga bekerja untuk 0. Jalankan dengan -r.

for($n=$argv[1];count_chars($s="$n",3)<2&$s>1;)for($i=$n=0;""<$c=$s[$i++];)$n+=$n+$c;echo$s;

count_chars($s,3)mengembalikan string yang berisi semua karakter dari string (seperti array_uniqueuntuk array). Untuk angka biner, ini akan menjadi 0, 1atau 01. Untuk nomor lain, ini akan berisi digit lebih besar dari 1, jadi hanya <2akan mengembalikan true untuk angka biner.

&$s>1 diperlukan untuk kasus khusus 1 .

Sisanya lurus ke depan: Loop melalui bit dengan menggeser nilai dan menambahkan bit saat ini, akhirnya menyalin angka (dilemparkan ke string) ke $ s untuk tes loop luar.

Titus
sumber
0

CoffeeScript, 92 89 byte

f=(x)->x>1&/^[01]+$/.test(x)&&f(''+x.split('').reverse().reduce ((p,v,i)->p+v*2**i),0)||x

JavaScript (ES6), 105 101 90 byte

f=y=>y>1&/^[01]+$/.test(y)?f(''+[...y].reverse().reduce(((p,v,i)=>p+v*Math.pow(2,i)),0)):y

Demo

Hanya berfungsi di browser yang sesuai dengan ES6 seperti Firefox dan Microsoft Edge

f=y=>y>1&/^[01]+$/.test(y)?f(''+[...y].reverse().reduce(((p,v,i)=>p+v*Math.pow(2,i)),0)):y

// Snippet stuff
$(`form`).submit((e) => {
  document.getElementById(`y`).textContent = f(document.getElementById(`x`).value);
  e.preventDefault()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <label>Input:
    <input pattern=^[01]+$ required id=x>
  </label>
  <button type=submit>Go</button>
  <p>Output:
    <output id=y></output>
  </p>
</form>

rink.attendant.6
sumber
Jika Anda menggunakan eval, Anda mungkin dapat melakukan pengembalian implisit.
Mama Fun Roll
5 byte lebih pendek dengan fungsi eval dan anonim
Downgoat
@ ן nɟuɐɯɹɐ ן oɯ Untuk beberapa alasan fungsi eval'd tidak berfungsi 1. karena itu tidak masuk ke loop saya berasumsi
rink.attendant.6
1
@nderscore Terima kasih, tetapi rekursi lebih pendek 4 byte :-)
rink.attendant.6
0

Scala, 128 byte

def b(s:String):String=if(s.matches("[10]{2,}"))b(""+s.reverse.zipWithIndex.collect{case('1',i)=>Math.pow(2,i)}.sum.toInt)else s
Yakub
sumber
0

Matlab (115)

@(a)num2str(sum((fliplr(a)-48).*arrayfun(@(x)2^x,0:nnz(a)-1)));a=ans(input('','s'));while(find(a<50))a=ans(a);end,a

  • Fungsi anonim adalah konversi tipe angka ( bin2dec)
Abr001am
sumber