Đơn giản hóa nhị phân


20

Thử thách

Cho một số nhị phân làm đầu vào thông qua bất kỳ phương tiện nào, "đơn giản hóa" số đó bằng cách sử dụng một chương trình đầy đủ hoặc một hàm.

Đầu vào

[binary]
  • binary là một số trong nhị phân lớn hơn 0.

Đầu ra

Lấy đầu vào, chuyển đổi nó thành cơ sở 10 mà không sử dụng nội dung, sau đó nếu số đó chỉ chứa 1 và 0, hãy chuyển đổi nó thành số 10 cơ sở như thể đó là một số nhị phân khác. Lặp lại quá trình cho đến khi số không thể được đọc ở dạng nhị phân và xuất số đó.

Thông tin khác

  • Nếu đầu vào là 1, chỉ cần đầu ra 1. Chương trình của bạn không nên tiếp tục đơn giản hóa vô hạn 1.

  • Đây là mã golf, vì vậy câu trả lời ngắn nhất tính bằng byte vào thứ ba (ngày 17 tháng 11) sẽ thắng.

  • Nếu có gì khó hiểu, hãy để lại một bình luận chỉ rõ những gì tôi cần làm rõ và tôi sẽ chỉnh sửa nó cho phù hợp.

  • Nội dung cho chuyển đổi cơ sở không được phép.

Ví dụ

     Input | Output

         1 | 1
      1010 | 2
      1011 | 3
   1100100 | 4
   1100101 | 5
1111110011 | 3

4
Có thể sử dụng một vài trường hợp thử nghiệm.
isaacg

Đầu vào là một chuỗi ASCII, hay thực tế là 1 và 0?
Tom Carpenter

@TomCarpenter 1s và 0s.
The_Basset_Hound

@isaacg Đã thêm các cách để có được 1-5 làm đầu ra.
The_Basset_Hound

Các hàm chuyển đổi một chuỗi thành một cơ sở nhất định có được phép không?
isaacg

Câu trả lời:


14

Bình thường, 20 16 byte

u?-GTG`u+yNsTG0z

4 byte nhờ Jakube

Một nửa mã ( u+yNsTG0) chỉ đơn giản là mã chuyển đổi cơ sở.

Phòng thử nghiệm

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.

Đầu vào 1được xử lý bởi thực tế là uthông báo giá trị đã ngừng thay đổi.


4
Xin chúc mừng, bạn đã vượt qua Dennis! Hiện tại ...
Conor O'Brien

9
@ CᴏɴᴏʀO'Bʀɪᴇɴ Bí mật là Pyth.
isaacg

8

CJam, 24 23 byte

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

Hãy thử trực tuyến trong trình thông dịch CJam .

Làm thế nào nó hoạt động

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.

Bạn có phải lặp lại số lần "10"chuỗi length-1, hoặc bạn có thể bỏ qua việc giảm?
DLosc

Trừ 1 từ độ dài biến "10"thành ""nếu số nguyên có một chữ số. Điều này đảm bảo mã không đi vào một vòng lặp vô hạn.
Dennis

2
Hấp dẫn, đội trưởng. }: ^ |
DLosc

7

Pip, 28 27 byte

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

Đưa đầu vào làm đối số dòng lệnh. Chúng tôi muốn lặp cho đến khi a=1hoặc achứa một số ký tự bên cạnh 0 và 1. Điều kiện sau này được kiểm tra bằng cách RM'ing tất cả các ký tự trong t= 10from a. Nếu có bất cứ điều gì còn lại, điều kiện là sự thật.

Trong vòng lặp, chuyển đổi hoạt động như sau:

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

Đặt aở cuối tự động in nó.

Một giải pháp đệ quy trong 28 byte:

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

6

Con trăn 2, 52

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

Dễ dàng hơn khi nghĩ về điều này như hai hàm đệ quy:

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

Hàm gchuyển đổi một giá trị thập phân thành nhị phân và hàm fáp dụng glặp đi lặp lại miễn là đối số của nó được tạo từ các chữ số 0 và 1 ( '2'>max(`n`)) và không 1. Mã đánh gôn thu gọn chúng thành một hàm duy nhất bằng cách chèn định nghĩa g(n)cho f(n), thay thế cuộc gọi đệ quy gbằng f. Các trường hợp cơ bản n=0của gđược tự động xử lý bởi kiểm tra n>1.


Đẹp :) Điều duy nhất là vấn đề thông thường được áp dụng - pesky Ltừ 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).

Giải thích
p là chức năng chính và thực hiện các bước sau (với sự trợ giúp từ b, x, y):

  • kiểm tra nếu số hiện tại lớn hơn 1
  • chuyển đổi số nguyên thành danh sách biểu diễn ascii của các chữ số
  • kiểm tra xem tất cả các số là 0 hay 1
  • chuyển đổi danh sách ascii thành danh sách số nguyên nhị phân
  • chuyển đổi danh sách số nguyên nhị phân thành số thập phân
  • đệ quy
  • in khi một vị ngữ không thành công

Chỉnh sửa: Đã lưu 8 byte bằng cách thống nhất các mệnh đề p với OR.


3

Toán học 107 106

Với một byte được lưu bởi 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])

Chia đầu vào thành các chữ số của nó. Nếu đầu vào là 1, đầu ra 1.

Nếu đầu vào là một số bao gồm 0 và 1, hãy chuyển đổi nó thành số thập phân và chạy lại.

Nếu không, trả lại đầu vào.


j[1]

1


j[11010001]

209


j[1111110001]

1009


j[1111110011]

3

Bước đầu tiên mang lại 1011, lần lượt mang lại 3.


Ở đây chúng tôi kiểm tra bắt đầu với 1011.

j[1011]

3


3

Javascript, 132 , 123 byte

Chà, đó không phải là câu trả lời hay nhất, nhưng ..

FYI, nếu một đầu vào không hợp lệ được đưa ra, nó sẽ hiển thị giống với người dùng.

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())


1
Bạn có thể lưu 19 byte bằng cách sử dụng forthay vì whilevà đặt giá trị trực tiếp trong câu lệnh (điều này cũng làm giảm một số {}), loại bỏ một số ;, sử dụng mô tả chức năng ES6, tăng inội tuyến. Nó sẽ trông như thế này : 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()).
insertusernamehere

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, cảm ơn vì lời đề nghị, nhưng tôi không hiểu c=x=>ngay từ đầu, đã không hoạt động trên bảng điều khiển Chrome hoặc Firefox. :( @ nɟuɐɯɹɐ oɯ, không thể quấn đầu với điều kiện XOR và x=0|x/10‌thay vào đó parseInt, tôi đã kết hợp các thay đổi còn lại. Cảm ơn ..
LearningDeveloper

@GauthamPJ Tôi xin lỗi, bằng cách nào đó, mã bị hỏng trong khi sao chép và chứa các ký tự không thể in được. Đây là phiên bản chính xác : 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()). Nó chắc chắn chạy trong Firefox 42, hãy thử điều này . Lưu ý rằng phiên bản được đánh gôn nhiều hơn và mã gốc của bạn không hoạt động 1và sẽ chạy vào một vòng lặp vô tận. c=x=>giống như function c(x){}xem " Hàm mũi tên ".
insertusernamehere

2

JavaScript ES6, 52

Là một chức năng. Đối số hàm phải là một chuỗi các chữ số nhị phân hoặc một số có biểu diễn thập phân chỉ chứa 1 và 0.

Kiểm tra chạy đoạn mã dưới đây trong trình duyệt tuân thủ EcmaScript 6 - thực hiện các chức năng mũi tên, chuỗi mẫu và toán tử trải rộng (Tôi sử dụng 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>


1
Thực sự thích n+=+c+ncho việc chuyển đổi nhị phân. Thật thanh lịch ...
nderscore

2

Toán học, 62 59 55 48 byte

Đã lưu 7 byte nhờ Martin Büttner.

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

1

Javascript (ES7) 87 80 78 77 74 byte

Đoạn giới thiệu đoạn trích để hỗ trợ các trình duyệt (hiện tại chỉ có Firefox hỗ trợ toán tử theo cấp số nhân)

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

Đoạn giới thiệu cho các trình duyệt hỗ trợ

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>




1

PHP, 210 204 byte

Đây là lần đầu tiên tôi đăng bài ở đây, vì vậy hy vọng các bạn sẽ thích nó! Ngay cả khi đó rõ ràng không phải là cách tốt nhất để viết nó, tôi vẫn vui mừng khoe nó ở đây!

Mật mã

<?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]);

Tôi đã tạo một hàm đệ quy "j" trước tiên sẽ kiểm tra xem đầu vào có bằng 1. Nếu vậy, hàm trả về 1 như mong đợi, nếu không, nó sẽ chia số trong một mảng để tính giá trị thập phân, nhưng chỉ nếu số là số nhị phân. Nếu không, nó sẽ trả về số như hiện tại.

Mã bị đánh cắp

<?
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]);

Tôi đã sử dụng câu lệnh "foreach" thay cho câu lệnh "for" ban đầu của mình, cho phép tôi tăng thêm 6 byte nhưng tôi khá chắc chắn còn nhiều việc phải làm.


1

PHP, 114 112 byte

cũng làm việc cho 0. Chạy với -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)trả về một chuỗi chứa tất cả các ký tự từ chuỗi (giống như array_uniqueđối với mảng). Đối với số nhị phân, điều này sẽ 0, 1hoặc 01. Đối với các số khác, số này sẽ chứa một chữ số lớn hơn 1, do đó <2sẽ chỉ trả về true cho các số nhị phân.

&$s>1là cần thiết cho trường hợp đặc biệt 1.

Phần còn lại là thẳng về phía trước: Lặp lại các bit với việc dịch chuyển giá trị và thêm bit hiện tại, cuối cùng sao chép số (truyền thành chuỗi) sang $ s để kiểm tra vòng lặp bên ngoài.


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

Bản giới thiệu

Chỉ hoạt động trong các trình duyệt tương thích ES6 như Firefox và 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>


Nếu bạn sử dụng eval, bạn có thể có được lợi nhuận ngầm.
Mama Fun Roll


@ Nɟuɐɯɹɐ ן oɯ Vì một số lý do, chức năng eval'd không hoạt động 1. bởi vì nó không đi vào vòng lặp mà tôi giả sử
rink.attguard.6

1
@nderscore Cảm ơn, nhưng đệ quy ngắn hơn 4 byte :-)
rink.attguard.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

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

  • Hàm ẩn danh là chuyển đổi loại số ( bin2dec)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.