ลดความซับซ้อนของไบนารี


20

ท้าทาย

ให้เลขฐานสองเป็นอินพุตโดยใช้วิธีการใดก็ได้ "ลดความซับซ้อน" จำนวนโดยใช้โปรแกรมเต็มรูปแบบหรือฟังก์ชั่น

อินพุต

[binary]
  • binary เป็นตัวเลขในเลขฐานสองที่มากกว่า 0

เอาท์พุต

รับอินพุตแปลงเป็นฐาน 10 โดยไม่ต้องใช้บิวอินจากนั้นถ้าตัวเลขนั้นมีเพียง 1s และ 0s ให้แปลงเป็นตัวเลขฐาน 10 ราวกับว่ามันเป็นเลขฐานสองอื่น ทำซ้ำกระบวนการจนกว่าจะไม่สามารถอ่านตัวเลขในไบนารีและเอาท์พุทตัวเลขนั้น

ข้อมูลอื่น ๆ

  • ถ้าใส่คือ 1, 1เอาท์พุทเพียง โปรแกรมของคุณไม่ควรลดความซับซ้อนลง 1

  • นี่คือโค้ดกอล์ฟดังนั้นคำตอบที่สั้นที่สุดเป็นไบต์ภายในวันอังคาร (17 พฤศจิกายน) เป็นผู้ชนะ

  • หากมีสิ่งใดที่ทำให้เกิดความสับสนแสดงความคิดเห็นโดยระบุสิ่งที่ฉันต้องล้างข้อมูลและฉันจะแก้ไขตามนั้น

  • ไม่อนุญาตให้สร้างสำหรับการแปลงฐาน

ตัวอย่าง

     Input | Output

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

4
สามารถใช้กรณีทดสอบสองสามข้อ
isaacg

อินพุตเป็นสตริง ASCII หรือจริง ๆ แล้วคือ 1 และ 0
Tom Carpenter

@TomCarpenter 1 วินาทีและ 0 วินาที
The_Basset_Hound

@isaacg เพิ่มวิธีรับ 1-5 เป็นเอาต์พุต
The_Basset_Hound

ฟังก์ชั่นที่แปลงสตริงเป็นฐานที่อนุญาตหรือไม่
isaacg

คำตอบ:


14

Pyth, 20 16 ไบต์

u?-GTG`u+yNsTG0z

4 ไบต์ขอบคุณ Jakube

ครึ่งหนึ่งของรหัส ( u+yNsTG0) เป็นเพียงรหัสการแปลงพื้นฐาน

ชุดทดสอบ

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.

อินพุต1ถูกจัดการโดยข้อเท็จจริงที่uแจ้งว่าค่าหยุดการเปลี่ยนแปลง


4
ขอแสดงความยินดีคุณชนะเดนนิส! ในขณะนี้ ...
Conor O'Brien

9
@ CᴏɴᴏʀO'Bʀɪᴇɴความลับคือ Pyth
isaacg

8

CJam, 24 23 ไบต์

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

ลองใช้ออนไลน์ในล่าม CJam

มันทำงานอย่างไร

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.

คุณต้องทำซ้ำครั้ง"10"สตริงlength-1หรือคุณสามารถข้ามการลดลง?
DLosc

การลบ 1 จากความยาวจะเปลี่ยน"10"เป็น""จำนวนเต็มถ้ามีตัวเลขหนึ่งหลัก สิ่งนี้ทำให้แน่ใจว่ารหัสไม่ได้อยู่ในวงวนไม่สิ้นสุด
เดนนิส

2
กัปตันที่น่าสนใจ }: ^ |
DLosc

7

Pip, 28 27 ไบต์

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

รับอินพุตเป็นอาร์กิวเมนต์บรรทัดคำสั่ง เราต้องการที่จะห่วงจนa=1หรือaมีอักขระบาง (s) นอกเหนือจาก 0 และ 1 เงื่อนไขนี้หลังมีการทดสอบโดยRM'ไอเอ็นจีตัวละครทุกตัวในt= จาก10 aหากมีสิ่งใดเหลืออยู่สภาพเป็นความจริง

ภายในลูปการแปลงทำงานดังนี้:

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

วางaที่ท้ายอัตโนมัติพิมพ์มัน

โซลูชันแบบเรียกซ้ำใน 28 ไบต์:

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

6

Python 2, 52

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

ง่ายกว่าที่จะคิดว่านี่เป็นหน้าที่สองแบบเรียกซ้ำ:

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

ฟังก์ชั่นgแปลงค่าทศนิยมไบนารีและฟังก์ชั่นfใช้gซ้ำ ๆ เป็นเวลานานเป็นอาร์กิวเมนต์ของมันทำจากตัวเลข 0 และ 1 ( '2'>max(`n`)) 1และไม่ได้เป็น รหัสแข็งแรงเล่นกอล์ฟพังทลายลงมาให้เป็นฟังก์ชันเดียวโดยการใส่ความหมายของg(n)สำหรับf(n)เปลี่ยนโทร recursive กับg fกรณีฐานของn=0การมีการจัดการโดยอัตโนมัติโดยการตรวจสอบgn>1


ดี :) สิ่งเดียวคือปัญหาปกติที่ใช้ - น่ารำคาญLจากrepr...
Sp3000

4

Prolog, 220 212 ไบต์

:-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).

คำอธิบาย
pเป็นฟังก์ชั่นหลักและดำเนินการตามขั้นตอนต่อไปนี้ (ด้วยความช่วยเหลือจาก b, x, y):

  • ตรวจสอบว่าหมายเลขปัจจุบันมากกว่า 1
  • แปลงจำนวนเต็มเป็นลิสต์ของการแทนค่า ASCII ของตัวเลข
  • ตรวจสอบว่าตัวเลขทั้งหมดเป็น 0 หรือ 1
  • แปลงรายการ ASCII เป็นรายการเลขจำนวนเต็มไบนารี
  • แปลงรายการเลขจำนวนเต็มไบนารีเป็นเลขฐานสิบ
  • recurses
  • พิมพ์เมื่อเพรดิเคตล้มเหลว

แก้ไข:บันทึกแล้ว 8 ไบต์โดยยกเลิกการรวมคำสั่งย่อยด้วย OR


3

Mathematica 107 106

ด้วยไบต์ที่บันทึกโดย 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])

แบ่งอินพุตเป็นตัวเลข หากอินพุตคือ 1 ให้เอาต์พุต 1

หากอินพุตเป็นตัวเลขที่ประกอบด้วย 0 และ 1 ให้แปลงเป็นทศนิยมและเรียกใช้อีกครั้ง

มิฉะนั้นส่งคืนอินพุต


j[1]

1


j[11010001]

209


j[1111110001]

1009


j[1111110011]

3

ขั้นตอนแรกให้ผลตอบแทน 1,011 ซึ่งจะให้ผลตอบแทน 3


ที่นี่เราทดสอบเริ่มต้นด้วย 1,011

j[1011]

3


3

Javascript, 132 , 123 bytes

มันไม่ใช่คำตอบที่ดีที่สุด แต่ ..

FYI หากมีการป้อนข้อมูลที่ไม่ถูกต้องข้อมูลดังกล่าวจะแสดงให้ผู้ใช้เห็น

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
คุณสามารถบันทึก 19 ไบต์โดยใช้forแทนwhileและการตั้งค่าโดยตรงในคำสั่ง (สิ่งนี้จะช่วยลดบางส่วน{}) ทิ้งบางส่วน;โดยใช้คำอธิบายฟังก์ชั่น ES6, iอินไลน์ที่เพิ่มขึ้น 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())มันจะมีลักษณะเช่นนี้
นี่

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

@insertusername ที่นี่ขอบคุณสำหรับคำแนะนำ แต่ฉันไม่เข้าใจในc=x=>ตอนเริ่มต้นไม่ทำงานบนคอนโซล Chrome หรือ Firefox :( @ ןnɟuɐɯɹɐןoɯไม่สามารถห่อหัวของฉันรอบเงื่อนไข XOR และx=0|x/10‌แทนparseIntฉันได้รวมการเปลี่ยนแปลงที่เหลือขอบคุณ ..
LearningDeveloper

@GauthamPJ ฉันขอโทษรหัสบางอย่างผิดพลาดขณะคัดลอกและมีอักขระที่ไม่สามารถพิมพ์ได้ 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())ต่อไปนี้เป็นรุ่นที่ถูกต้อง: แน่นอนมันทำงานใน Firefox 42, ลองซอนี้ โปรดทราบว่าเวอร์ชัน golfed ที่มากขึ้นและรหัสต้นฉบับของคุณใช้งานไม่ได้1และจะทำงานเป็นวงวนไม่รู้จบ c=x=>ก็เหมือนfunction c(x){}เห็น " ฟังก์ชั่นลูกศร "
แทรกที่นี่

2

JavaScript ES6, 52

เป็นฟังก์ชั่น อาร์กิวเมนต์ฟังก์ชั่นจะต้องเป็นสตริงของเลขฐานสองหรือตัวเลขที่มีการแทนทศนิยมมีเพียง 1 และ 0

ทดสอบการเรียกใช้ตัวอย่างด้านล่างในเบราว์เซอร์ที่สอดคล้องกับ EcmaScript 6 - การใช้ฟังก์ชั่นลูกศร, สตริงของเทมเพลตและโอเปอเรเตอร์การแพร่กระจาย (ฉันใช้ 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
ความชื่นชอบn+=+c+nการแปลงแบบไบนารีจริงๆ สง่างามมาก ...
อ่าน

2

Mathematica, 62 59 55 48 ไบต์

บันทึกแล้ว 7 ไบต์ด้วย Martin Büttner

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

1

Javascript (ES7) 87 80 78 77 74 ไบต์

ตัวอย่างข้อมูลสำหรับการสนับสนุนเบราว์เซอร์ (ขณะนี้เฉพาะ Firefox ทุกคืนสนับสนุนผู้ให้บริการชี้แจง)

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 ไบต์

ตัวอย่างข้อมูลเพื่อรองรับเบราว์เซอร์

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

𝔼𝕊𝕄𝕚𝕟, 37 ตัวอักษร / 54 ไบต์

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

Try it here (Firefox only).

ไม่แน่ใจว่าตัว+ดำเนินการนับเป็นบิวด์อินสำหรับการแปลงแบบไบนารีหรือไม่ ...



1

PHP, 210 204 ไบต์

นี่เป็นครั้งแรกที่ฉันโพสต์ที่นี่ดังนั้นหวังว่าพวกคุณจะชอบมัน! แม้ว่ามันจะไม่ใช่วิธีที่ดีที่สุดในการเขียน แต่ฉันก็ยังดีใจที่ได้แสดงมันที่นี่!

รหัส

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

ฉันได้ทำซ้ำฟังก์ชัน "j" ที่จะตรวจสอบก่อนว่าอินพุตเท่ากับ 1 ถ้าใช่ฟังก์ชั่นกลับ 1 ตามที่คาดไว้มิฉะนั้นมันจะแบ่งจำนวนในอาร์เรย์เพื่อคำนวณค่าทศนิยม แต่เพียง ถ้าตัวเลขเป็นเลขฐานสอง หากไม่ใช่จะส่งคืนหมายเลขตามที่เป็น

รหัสที่ไม่ได้รับการปรับปรุง

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

ฉันใช้คำสั่ง "foreach" แทนคำว่า "for" one ซึ่งทำให้ฉันได้รับ 6 ไบต์ แต่ฉันค่อนข้างมั่นใจว่ามีอีกมากที่ต้องทำ


1

PHP, 114 112 ไบต์

0ยังสามารถใช้ได้กับ -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)ส่งคืนสตริงที่มีอักขระทั้งหมดจากสตริง (เช่นเดียวarray_uniqueกับอาร์เรย์) สำหรับเลขฐานสองนี้จะเป็น0, หรือ1 01สำหรับตัวเลขอื่น ๆ สิ่งนี้จะมีตัวเลขที่มากกว่า1ดังนั้น<2จะส่งกลับค่าจริงสำหรับเลขฐานสองเท่านั้น

&$s>11เป็นสิ่งจำเป็นสำหรับกรณีพิเศษ

ส่วนที่เหลือนั้นตรงไปตรงมา: วนรอบบิตด้วยการเลื่อนค่าและเพิ่มบิตปัจจุบันคัดลอกหมายเลข (cast to string) เป็น $ s สำหรับการทดสอบลูปนอก


0

CoffeeScript, 92 89 ไบต์

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 ไบต์

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

การสาธิต

ใช้ได้เฉพาะกับเบราว์เซอร์ที่สอดคล้องกับ ES6 เช่น Firefox และ 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>


หากคุณใช้ eval คุณอาจสามารถถอนการส่งคืนโดยนัยได้
Mama Fun Roll

สั้นลง 5 ไบต์ด้วยฟังก์ชั่น eval และไม่ระบุชื่อ
Downgoat

@ ןnɟuɐɯɹɐןoɯด้วยเหตุผลบางอย่างฟังก์ชั่น eval'd 1ไม่ได้ทำงานร่วมกับ เพราะมันไม่เข้าสู่ลูปฉันถือว่า
rink.attendant.6

1
@nderscore ขอบคุณ แต่การเรียกซ้ำมีความยาวน้อยกว่า 4 ไบต์ :-)
rink.attendant.6


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

  • ฟังก์ชั่นที่ไม่ระบุชื่อคือการแปลงประเภทตัวเลข ( bin2dec)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.