ย่อยสลายเลขฐานสองเป็นชุดย่อยสลับกัน


30

สิ่งนี้ได้รับแรงบันดาลใจจากปัญหาที่ 13 - ไบนารีที่ไม่ซ้ำของการแข่งขันล่าสุดของHP CodeWars

ลองใส่ตัวเลขทศนิยมแบบสุ่มพูด

727429805944311

และดูที่การเป็นตัวแทนไบนารี:

10100101011001011111110011001011101010110111110111

ตอนนี้แยกการเป็นเลขฐานสองนั้นออกเป็นอนุกรมที่ตัวเลข0และ1ทางเลือก

1010 010101 10 0101 1 1 1 1 1 10 01 10 0101 1 1010101 101 1 1 1 101 1 1

และแปลงแต่ละลำดับกลับเป็นทศนิยม

10 21 2 5 1 1 1 1 1 2 1 2 5 1 85 5 1 1 1 5 1 1

งาน

รับจำนวนเต็มบวกเดียวเป็นอินพุตและเอาต์พุตลำดับของจำนวนเต็มบวกที่ได้จากกระบวนการข้างต้น

รายละเอียด

  • อินพุตและเอาต์พุตต้องเป็นทศนิยมหรือไม่เป็นศูนย์
  • ตัวเลขในเอาต์พุตจะต้องแยกออกในแบบที่สมเหตุสมผลและอ่านง่ายและจะต้องเป็นทศนิยมหรือไม่เป็นเอกพจน์ ไม่มีข้อ จำกัด ในพื้นที่สีขาว รูปแบบการส่งออกที่ถูกต้อง: [1,2,3], 1 2 3, 1\n2\n3ที่\nมีการขึ้นบรรทัดใหม่ที่แท้จริง ฯลฯ

กรณีทดสอบ

 Input | Output
     0 | 0
     1 | 1
     2 | 2
     3 | 1 1
     4 | 2 0
     5 | 5
     6 | 1 2
     7 | 1 1 1
     8 | 2 0 0
     9 | 2 1
    10 | 10
    50 | 1 2 2
   100 | 1 2 2 0
  1000 | 1 1 1 1 10 0 0
 10000 | 2 1 1 2 0 2 0 0 0
 12914 | 1 2 2 1 1 2 2
371017 | 5 42 10 2 1

หมายเหตุเพิ่มเติม: ตัวเลขทั้งหมดในการส่งออกที่ควรจะเป็นในรูปแบบหรือ(2^k-1)/3 2*(2^k-1)/3นั่นคือ0 1 2 5 10 21, 42, 85, 170, ...ซึ่งคือA000975ใน OEIS


@DigitalTrauma: อืม ...... ไม่ฉันไม่คิดว่ามันเป็นสิ่งที่ท้าทาย
El'endia Starman

ตกลง. |tacจะยังคงอยู่ในคำตอบของฉัน :)
บาดเจ็บทางดิจิทัล

คำตอบ:


11

Pyth, 17 16 ไบต์

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

iR2cJ.BQx1qVJ+dJ

สาธิต

ทางออกที่ดีและฉลาด ใช้คุณสมบัติบางอย่างที่รู้จักกันน้อยของ Pyth เหมือนและx<int><list>c<str><list>

iR2cJ.BQx1qVJ+dJ
                    Q = eval(input())
    J.BQ            Store in J the input in binary.
          qV        Vectorize equality function over
            J+dJ    J and J with a leading dummy char, to get the offset right.
                    This calculates whether each element matches its successor.
        x1          Find all of the indexes of 1 (True) in this list.
   cJ                Chop J at those locations.
iR2                  Convert from binary back to base ten and output.

1
หากคุณแทนที่tJโดยคุณสามารถลบ+dJ hM
Jakube

@Jakube เป็นคนดี!
isaacg

7

Mathematica, 47 ไบต์

#+##&~Fold~#&/@#~IntegerDigits~2~Split~Unequal&

Ungolfed:

FromDigits[#,2]&/@Split[IntegerDigits[#,2],Unequal]&

Split[list,f]แยกรายการเป็นรายการหลายทำลายที่ตำแหน่งระหว่างaและbIFF ไม่ได้กลับf[a,b]True

FromDigits[n,2] => Fold[#+##&,n]เป็นเคล็ดลับเรียบร้อยจาก alephalpha


7

Python ขนาด 86 ไบต์

เนื่องจากฉันได้รับการตีอย่างน่ากลัวใน Pyth ให้ทำมันใน Python อีกครั้ง

import re
lambda n:[int(s,2)for s in re.sub("(?<=(.))(?=\\1)"," ",bin(n)[2:]).split()]

ลองที่นี่!

คำอธิบาย

เราเริ่มต้นด้วยการแปลงหมายเลขอินพุตnให้เป็นสตริงไบนารี bin(n)[2:]ดูแลสิ่งนั้น เราจำเป็นต้องทิ้ง 2 ตัวอักษรแรกของสายนี้ตั้งแต่ผลตอบแทนสตริงในรูปแบบที่bin() ต่อไปเราต้องระบุขอบเขตของส่วนประกอบ ซึ่งสามารถทำได้ด้วย regex ซึ่งตรงกับตำแหน่งที่มีความยาวเป็นศูนย์ในสตริงที่มีหมายเลขเดียวกันทางซ้ายและขวา วิธีที่ชัดเจนในการรับรายชื่อของทุกองค์ประกอบจะใช้ซึ่งแยกสตริงใน regex ที่แน่นอน น่าเสียดายฟังก์ชันนี้ใช้ไม่ได้กับการจับคู่ที่มีความยาวเป็นศูนย์ แต่โชคดีที่ทำเช่นนั้นเราเพียงแค่แทนที่การแข่งขันที่มีความยาวเป็นศูนย์ด้วยช่องว่างแล้วแยกสตริงออกหลังจากนั้น0b10101
(?<=(.))(?=\1)
re.split()re.sub()
จากนั้นเราก็ต้องแยกวิเคราะห์แต่ละส่วนของลำดับเหล่านั้นกลับเป็นตัวเลขทศนิยมด้วยint(s,2)และเสร็จแล้ว


4

เยลลี่ 12 ไบต์

BI¬-ẋż@BFṣ-Ḅ

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

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

BI¬-ẋż@BFṣ-Ḅ  Main link. Argument: n

B             Convert n to base 2.
 I            Compute the increments, i.e., the differences of consecutive digits.
  ¬           Apply logical NOT.
   -ẋ         Repeat -1 that many times, for the logical NOT of each difference.
              [0, 0] / [1, 1] ->   0    -> 1 -> [-1]
              [0, 1] / [1, 0] -> 1 / -1 -> 0 -> []
       B      Yield n in base 2.
     ż@       Zip the result to the right with the result to the left.
        F     Flatten the resulting list of pairs.
         ṣ-   Split at occurrences of -1.
           Ḅ  Convert each chunk from base 2 to integer.

12 ตัวอักษรอย่างแน่นอน แต่ 20 ไบต์ หรือคุณกำลังใช้ระบบที่มี CHAR_BIT >> 8
James Youngman

1
@JamesYoungman Jelly ไม่ได้ใช้ UTF-8 ตามค่าเริ่มต้น ในความเป็นจริงมันมีหน้ารหัสของตัวเองที่เข้ารหัสอักขระ 256 ตัวแต่ละตัวที่มันเข้าใจเป็นไบต์เดียว
Dennis

4

ยูทิลิตี Bash + GNU, 51

dc -e2o?p|sed -r ':;s/(.)\1/\1 \1/;t'|dc -e2i?f|tac

ข้อมูลที่นำมาจาก STDIN

  • dc -e2o?p อ่านจำนวนเต็มอินพุตจาก STDIN และส่งออกสตริงฐาน 2
  • sed -r ':;s/(.)\1/\1 \1/;t' แยกสตริงฐาน 2 ด้วยช่องว่างทุกที่ที่มีตัวเลขต่อเนื่องเหมือนกัน
  • dc -e2i?fอ่านไบนารี่แบบแยกในหนึ่งครั้งวางแต่ละส่วนลงบนสแต็กจากนั้นfทิ้งdcสแต็กทั้งหมด(หมายเลขเอาต์พุตในลำดับย้อนกลับ) ...
  • ... tacซึ่งได้รับการแก้ไขโดย

4

JavaScript (ES6) 58 62 63

แก้ไข 1 ไบต์ที่บันทึกไว้ขอบคุณ @ETHproductions

แก้ไข 4 ไบต์ที่บันทึกไว้ขอบคุณ @Neil

x=>x.toString(2).replace(/((.)(?!\2))*./g,x=>'0b'+x-0+' ')

f=x=>x.toString(2).replace(/((.)(?!\2))*./g,x=>'0b'+x-0+' ')

 
console.log=x=>O.textContent+=x+'\n'

;[
[     0,'0'],
[     1,'1'],
[     2,'2'],
[     3,'1 1'],
[     4,'2 0'],
[     5,'5'],
[     6,'1 2'],
[     7,'1 1 1'],
[     8,'2 0 0'],
[     9,'2 1'],
[    10,'10'],
[    50,'1 2 2'],
[   100,'1 2 2 0'],
[  1000,'1 1 1 1 10 0 0'],
[ 10000,'2 1 1 2 0 2 0 0 0'],
[ 12914,'1 2 2 1 1 2 2'],
[371017,'5 42 10 2 1']
].forEach(t=>{
  var i=t[0],k=t[1],r=f(i)
  console.log(i+' -> '+r+(r.trim()==k.trim() ? ' ok':'ko (should be '+k+')'))
})
<pre id=O></pre>


คุณสามารถบันทึกสองไบต์ด้วย regex /(01)*0?|(10)*1?/gหรือว่าจะสับสนอะไรขึ้น
ETHproductions

1
นอกจากนี้ฉันคิดว่าคุณสามารถทำได้x=>'0b'+x-0+' 'เพื่อบันทึกไบต์
ETHproductions

@ ETHproductions ฉันลอง regexp ที่สั้นกว่าไม่ดี :( ขอบคุณสำหรับคำใบ้อื่น ๆ
edc65

Leadboard บอกว่าคุณมีคำตอบ 1 ไบต์ ฉันคิดว่าเป็นเพราะคุณมีหมายเลขที่ถูกต้อง (62) ก่อนหมายเลขเก่า (63) แทนที่จะเป็นหลัง
Kyle Kanos

ฉันคิดว่า regex /((.)(?!\2))*./gช่วยให้คุณประหยัด 4 ไบต์ที่ยอดเยี่ยม
Neil

3

Pyth, 26 ไบต์

iR2c:.BQ"(?<=(.))(?=\\1)"d

ลองที่นี่!

คำอธิบาย

iR2c: .BQ "(? <= (.)) (? = \\ 1)" d # Q = หมายเลขอินพุต

     .BQ # แปลงอินพุตเป็นไบนารี
    : "(? <= (.)) (? = \\ 1)" d # แทรกช่องว่างระหว่างองค์ประกอบ
   c # แยกสตริงบน whitespaces
iR2 # แปลงแต่ละลำดับเป็นทศนิยม

เนื่องจากฟังก์ชัน split () ของ Python ไม่ได้แยกจากการแข่งขันที่มีความยาวเป็นศูนย์ฉันจึงต้องแทนที่การแข่งขันเหล่านั้นด้วยการเว้นวรรคและแยกผลลัพธ์ออกมา


3

Pyth, 22 21 ไบต์

&Qu?q%G2H&
GH+yGHjQ2Z

ลองใช้งานออนไลน์: การสาธิต

เป็นงานที่น่าเบื่อจริงๆใน Pyth

คำอธิบาย:

&Qu?q%G2H&\nGH+yGHjQ2Z   implicit: Q = input number
                  jQ2    convert Q to base 2
  u               jQ2Z   reduce ^: for each digit H update the variable G=0:
   ?q%G2H                   if G%2 == H:
          \nG                  print G
         &   H                 then update G with H
              +yGH           else: update G with 2*G+H
  u                      print the last G also
&Q                       handle Q=0 special: only print 0 once

3

05AB1E , 18 ไบต์

รหัส:

b2FNð«N«Dð-s:}ð¡)C

คำอธิบาย:

b                   # Convert input to binary
 2F          }      # Do the following twice ( with N as range variable)
   Nð«N«            #    N + space + N
        D           #    Duplicate this
         ð-         #    Delete spaces from the duplicate string
           s        #    Swap the top two elements
            :       #    Replace the first string with the second
              ð¡    # Split on spaces
                )   # Wrap into an array
                 C  # Convert all element back to decimal

ลองออนไลน์!

ใช้การเข้ารหัสCP-1252


3

MATL , 18 17 ไบต์

YBTyd~Thhfd1wY{ZB

ลองออนไลน์!

YB      % input number. Convert to binary string
T       % push true value
y       % duplicate binary string and push it at the top of the stack
d~      % true for each value that equals the previous one
T       % push true value
hh      % concatenate: true, indices, true
f       % find indices of true values
d       % consecutive differences: lenghts of alternating sequences
1wY{    % split binary string according to those lengths
ZB      % convert each substring into decimal number

3

zsh, 67 63 55 ไบต์

for i in `grep -oP '1?(01)*0?'<<<$[[##2]$1]`;<<<$[2#$i]

ฉันไม่รู้ว่าทำไม แต่สิ่งนี้ไม่ได้ผลใน Bash

ขอบคุณเดนนิสสำหรับ 8 ไบต์!


มันเป็นforไวยากรณ์ ... รอไม่fors?
CalculatorFeline

การขยายเลขคณิตของ Bash ไม่อนุญาตให้คุณระบุฐานเอาท์พุท เพื่อกำจัด xargs for i in `grep -oP '1?(01)*0?'<<<$[[##2]$1]`;<<<$[2#$i]คุณสามารถใช้
Dennis

2

PHP, 171 168 162 160 158 121 120 131 124 118 116 113 112 ไบต์

function d($i){for(;$d<$l=strlen($b=decbin($i));){$c.=$u=$b[$d];echo$u==$b[++$d]||$d==$l?bindec($c).$c=" ":"";}}
มุมมองการระเบิด
function d($i) {
  for ( ; $d < $l = strlen($b = decbin($i)); ) {
    $c .= $u = $b[$d];
    echo $u == $b[++$d] || $d == $l ? bindec($c) . $c = " "
                                    : "";
  }
}

ใช้d(int)และคุณปิดอยู่เอาต์พุตคือechoสตริง ed ของintคั่นด้วยช่องว่าง

การแก้ไข:
-3:ย้าย$bคำจำกัดความไปยังการstrlen()โทร
-6:ลบการ$cเริ่มต้น
-2: ในที่สุดแก้ไขปัญหาการตัดแบ่ง
-2:ไม่มีวงเล็บสำหรับบรรทัดfor()เดียว
-37: การ ยกเครื่องทั้งหมด ไปกับArraychunklets แทนซ้ำArray-> String-> Arrayโทร
-1:$cรีเซ็ตส่อเสียด
+11: การ แก้ไขข้อผิดพลาด ขาดชิ้นสุดท้าย ไม่มีอีกแล้ว
-7:ไม่จำเป็นต้องยกตัวอย่าง$dเลย? ดี
-6: ->return -2:กระทืบ -3:echo
$c
Ternary ที่รักครั้งแรกของฉัน
-1:$uส่อเสียดส่อเสียด


ฉันคิดว่าคุณสามารถบันทึก 2 function d($i){for(;$d<$l=strlen($b=decbin($i));print$u==$b[++$d]||$d==$l?bindec($c).$c=" ":"")$c.=$u=$b[$d];}ไบต์:
Blackhole

2

นูน 0.2+, 25 ไบต์

นูนเป็นภาษาใหม่ที่ฉันกำลังพัฒนาซึ่งขึ้นอยู่กับ CJam และ Golfscript เป็นอย่างมาก ล่ามและ IDE สามารถพบได้ที่นี่ อินพุตเป็นจำนวนเต็มในอาร์กิวเมนต์บรรทัดคำสั่ง สิ่งนี้ใช้การเข้ารหัสCP-1252

2bs®(?<=(.))(?=\\1)"ö2fbp

คำอธิบาย:

2bs                         Convert to binary string
   ®(?<=(.))(?=\\1)"        Regex literal
                    ö       Split string on regex
                     2fb    Convert each split string into decimal integer
                        p   Print resulting array

2

Java 8, 127 119 ไบต์

l->new java.util.ArrayList<Long>(){{for(String s:l.toBinaryString(l).split("(?<=(.))(?=\\1)"))add(l.parseLong(s,2));}};

อาจมีนิพจน์ทั่วไปที่ดีกว่าเพื่อแยกสตริงออก ฉันไม่เก่งที่ regex แต่ฉันจะทำการทดลองต่อไป

-8 ไบต์ขอบคุณ @FryAmTheEggman


2

APL (APL) , 21 25 ไบต์

ตอนนี้จัดการ 0 เช่นกัน

{0::0⋄2⊥¨⍵⊂⍨1,2=/⍵}2⊥⍣¯1⊢

ลองออนไลน์!

2⊥⍣¯1⊢ แปลงเป็น base-2 โดยใช้จำนวนบิตมากเท่าที่ต้องการ (lit. inverse from-base-2 conversion)

{} ใช้ฟังก์ชั่นที่ไม่ระบุชื่อต่อไปนี้

0:: หากมีข้อผิดพลาดเกิดขึ้น:

  0 กลับ 0

 ตอนนี้ลอง:

  2=/⍵ ความเสมอภาคแบบคู่ของอาร์กิวเมนต์ (จะทำให้การแสดงไบนารีความยาว 0 หนึ่งของ 0 ล้มเหลว)

  1, เสริม 1

  ⍵⊂⍨ ใช้เพื่อแบ่งอาร์กิวเมนต์ (เริ่มหัวข้อใหม่ในแต่ละ 1)

  2⊥¨ แปลงแต่ละตัวจากฐาน -2


1
มีประโยชน์จริง ๆ ที่นี่ ฉันควรเพิ่มเข้าไปในเยลลี่
Dennis

@Dennis ทราบถึงสองเวอร์ชันR←X⊂Y: ด้วย⎕ML<3(เช่นรูปแบบ Dyalog) พาร์ติชั่นใหม่จะเริ่มต้นในผลลัพธ์ที่สอดคล้องกับแต่ละ 1 ใน X จนถึงตำแหน่งก่อนหน้า 1 ถัดไปใน X (หรือองค์ประกอบสุดท้ายของ X) กลายเป็น รายการที่ต่อเนื่องของ R ด้วย⎕ML=3(เช่นสไตล์ IBM) พาร์ติชันใหม่จะเริ่มขึ้นในผลลัพธ์เมื่อใดก็ตามที่องค์ประกอบที่สอดคล้องกันใน X มากกว่าอันก่อนหน้านี้ รายการใน Y ที่สอดคล้องกับ 0s ใน X จะไม่รวมอยู่ในผลลัพธ์ ดังนั้นจึง⎕ML←1 ⋄ 1 0 0 1 0 1 1 ⊂ ⍳7เท่ากับ⎕ML←3⋄ 4 3 2 4 4 5 7 ⊂⍳7`
Adám


1

Python 3, 115 ไบต์

def f(s):
 s=bin(s);r=[s[2]]
 for i in s[3:]:
  if i==r[-1][-1]:r+=[i]
  else:r[-1]+=i
 return[int(x,2)for x in r]

คำอธิบาย

def f(s):
 s=bin(s)                   # convert input in binary
 r=[s[2]]                   # initialize the result with the first char after the 'b' in binary string
 for i in s[3:]:            # loop on other element
  if i==r[-1][-1]:          # if the last element of the last string equal the current element 
   r+=[i]                   # we add the current element in a new string
  else:
   r[-1]+=i                 # we add the current element to the last sting
 return[int(x,2)for x in r] # convert binary string in integer 

ผล

>>> [print(i,f(i)) for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 50, 100, 1000, 10000, 12914, 371017]]
0 [0]
1 [1]
2 [2]
3 [1, 1]
4 [2, 0]
5 [5]
6 [1, 2]
7 [1, 1, 1]
8 [2, 0, 0]
9 [2, 1]
10 [10]
50 [1, 2, 2]
100 [1, 2, 2, 0]
1000 [1, 1, 1, 1, 10, 0, 0]
10000 [2, 1, 1, 2, 0, 2, 0, 0, 0]
12914 [1, 2, 2, 1, 1, 2, 2]
371017 [5, 42, 10, 2, 1]

โซลูชันก่อนหน้า (118 ไบต์)

def f(s):
 s=bin(s);r=s[2]
 for i in s[3:]:
  if i==r[-1]:r+='a'+i
  else:r+=i
 return[int(x,2)for x in r.split('a')]

1

Haskell, 147 , 145 bytes

x%[]=[x]
x%(y:z)|or.(zipWith(==)<*>tail)$y:x=x:[]%(y:z)|1<2=(y:x)%z
b x|x<2=[x]|1<2=b(div x 2)++[mod x 2]
map(sum.zipWith((*).(2^))[0..]).([]%).b

map(sum.zipWith((*).(2^))[0..]).([]%).b เป็นฟังก์ชันที่ไม่มีชื่อที่คำนวณรายการ

หักกอล์ฟ:

alternating :: Eq a => [a] -> Bool
alternating = or . (zipWith (==) <*> tail)

-- (%) is the partitioning function
(%) :: Eq a => [a] -> [a] -> [[a]]
x % [] = [x]

x % (y:z) | alternating (y : x) = x : [] % (y:z)
          | otherwise = (y : x) % z

bits :: Integral t => t -> [t]
bits x | x < 2     = [x] 
       | otherwise = bits (div x 2) ++ [mod x 2]

unBits :: Num c => [c] -> c
unBits = sum . zipWith ((*) . (2^)) [0..]

f :: Integer -> [Integer]
f = map unBits . ([]%) . bits


1

PowerShell, 103 ไบต์

[regex]::Matches([convert]::ToString($args[0],2),"(01)+0?|(10)+1?|.").Value|%{[convert]::toint32($_,2)}

ตั้งแต่ฉันน่ากลัวที่ regex ฉันใช้การแสดงออกเช่นเดียวกับ คำตอบของ edc65

ถูกทำลายอย่างแน่นอนโดยการเรียก. NET ที่มีความยาวเพื่อทำการแปลงเป็น / จากไบนารีและการเรียก. NET เพื่อรับการจับคู่ regex อย่างอื่นตรงไปตรงมาสวย นำเข้า$args[0], converts ไปยังไบนารี, ป้อนเข้าMatches, นำผลลัพธ์.Value, ท่อผ่านห่วง|%{...}และconverts ค่าเหล่านั้นกลับไปintค่าเหล่านั้นกลับไป เอาต์พุตถูกทิ้งไว้บนไพพ์ไลน์และพิมพ์ด้วยบรรทัดใหม่โดยปริยาย


สำหรับเครดิตพิเศษ - รุ่นที่ไม่ใช่ regex (ส่วนใหญ่) ที่ 126 ไบต์

$l,$r=[char[]][convert]::ToString($args[0],2);$l+-join($r|%{(" $_",$_)[$l-bxor$_];$l=$_})-split' '|%{[convert]::toint32($_,2)}

เราป้อนข้อมูลอีกครั้ง $args[0]และconvertไปเป็นเลขฐานสอง เราอีกครั้งในขณะที่ถ่านอาร์เรย์จัดเก็บตัวอักษรตัวแรกในและตัวอักษรที่เหลือใน$l $rจากนั้นเราส่ง$rผ่านการวนซ้ำ|%{...}ซึ่งการวนซ้ำทุกครั้งที่เราเลือกจากตัวละครที่เติมด้วยช่องว่างหรือเพียงแค่ตัวละครขึ้นอยู่กับผลลัพธ์ของไบนารี xor ด้วย$lแล้วตั้ง$lค่าให้เท่ากับตัวละคร สิ่งนี้ทำให้มั่นใจได้ว่าหากเรามีตัวละครเดียวกันสองครั้งติดต่อกันเราจะเพิ่มช่องว่างระหว่างพวกเขา

ผลลัพธ์ของลูปจะถูก-joinรวมเข้าด้วยกันและผนวกเข้ากับอักขระตัวแรก$lจากนั้น-splitเว้นวรรค (ซึ่งเป็นเทคนิค regex แต่ฉันจะไม่นับ) จากนั้นเราจะทำลูปเดียวกันกับคำตอบของ regexconvertและจำนวนเต็มเอาท์พุท


1

Java 345 ไบต์

package com.ji.golf;
import java.util.regex.*;
public class Decompose {
  public static String decompose(long l) {
    String o="";
    String s=Long.toBinaryString(l);
    Matcher m=Pattern.compile("(01)+(0)?|(10)+(1)?|(1)|(0)").matcher(s);
    while(m.find()){String c=s.substring(m.start(),m.end());o+=Integer.parseInt(c, 2)+" ";}
    return o;
  }
}

ทดสอบ

package com.ji.golf;
public class DecompseTest {
  public static void main(String[] args) {
    String[] inOut = new String[]{
        "0,0",
        "1,1",
        "2,2",
        "3,1 1",
        "4,2 0",
        "5,5",
        "6,1 2",
        "7,1 1 1",
        "8,2 0 0",
        "9,2 1",
        "10,10",
        "50,1 2 2",
        "100,1 2 2 0",
        "1000,1 1 1 1 10 0 0",
        "10000,2 1 1 2 0 2 0 0 0",
        "12914,1 2 2 1 1 2 2",
        "371017,5 42 10 2 1"
    };
    for (String s : inOut) {
      String[] io = s.split(",");
      String result = Decompose.decompose(Long.parseLong(io[0]));
      System.out.println("in: " + io[0] + ", reusult: [" +  result.trim() + "], validates? " + result.trim().equals(io[1].trim()));
    }
  }
}

เอาท์พุต

in: 0, reusult: [0], validates? true
in: 1, reusult: [1], validates? true
in: 2, reusult: [2], validates? true
in: 3, reusult: [1 1], validates? true
in: 4, reusult: [2 0], validates? true
in: 5, reusult: [5], validates? true
in: 6, reusult: [1 2], validates? true
in: 7, reusult: [1 1 1], validates? true
in: 8, reusult: [2 0 0], validates? true
in: 9, reusult: [2 1], validates? true
in: 10, reusult: [10], validates? true
in: 50, reusult: [1 2 2], validates? true
in: 100, reusult: [1 2 2 0], validates? true
in: 1000, reusult: [1 1 1 1 10 0 0], validates? true
in: 10000, reusult: [2 1 1 2 0 2 0 0 0], validates? true
in: 12914, reusult: [1 2 2 1 1 2 2], validates? true
in: 371017, reusult: [5 42 10 2 1], validates? true

4
ยินดีต้อนรับสู่ Programming Puzzles & Code Golf! เนื่องจากนี่เป็นการแข่งขันกอล์ฟรหัสคุณควรทำให้รหัสของคุณสั้นที่สุด นี่คือเคล็ดลับบางประการสำหรับการเล่นกอล์ฟใน Java คุณสามารถเริ่มต้นด้วยการกำหนดฟังก์ชั่นของคุณโดยไม่ต้องใช้แผ่นสร้างpackageและclassและลบช่องว่างที่ไม่จำเป็น แจ้งให้เราทราบหากคุณมีข้อสงสัย!
Alex A.

1

Julia, 70 57 ไบต์

n->map(i->parse(Int,i,2),split(bin(n),r"(?<=(.))(?=\1)"))

นี่คือฟังก์ชั่นที่ไม่ระบุชื่อที่รับจำนวนเต็มและส่งกลับอาร์เรย์จำนวนเต็ม หากต้องการเรียกใช้กำหนดค่าให้กับตัวแปร

วิธีการที่นี่จะคล้ายกับ DenkerAffe ของดีหลามคำตอบ เราได้รับแทน binary ของnใช้และแยกสตริงที่เกิดขึ้นในการแข่งขันทั้งหมดของการแสดงออกปกติbin(n) (?<=(.))(?=\1)จริงๆแล้วมันเป็นการแข่งขันที่ไม่มีความยาว (?<=(.))เป็น lookbehind เชิงบวกที่ค้นหาอักขระเดี่ยวใด ๆ และ(?=\1)เป็น lookahead เชิงบวกที่ค้นหาอักขระที่ตรงกันใน lookbehind นี้จะหาสถานที่ที่ตัวเลขตามด้วยตัวเองในการเป็นตัวแทนไบนารี เพียงแค่parseแต่ละจำนวนเต็มในฐาน 2 โดยใช้mapและ voila!


1

C, 137 129 ไบต์

main(){unsigned long a,b=scanf("%lu",&a),c=!!a;while(a>=b*2)b*=2;while(b)b/=2,c=c*(~(a^a/2)&b|!b?!printf("%lu\n",c):2)+!!(a&b);}

อินพุตและเอาต์พุตอยู่บนสตรีมมาตรฐาน


ฉันไม่คิดว่าคุณต้องการputsแม้ว่ามันจะไม่เป็นที่พอใจที่จะใช้ข้อมูลจำเพาะไม่จำเป็นต้องขึ้นบรรทัดใหม่
FryAmTheEggman

@FryAmTheEggman ฉันไม่ต้องการสร้างบรรทัดสุดท้ายที่ไม่สมบูรณ์ แต่สำหรับค่าใช้จ่ายของหนึ่งไบต์ (ยังคงลดลงสุทธิ) ฉันสามารถเปลี่ยนตัวคั่นจากพื้นที่เพื่อขึ้นบรรทัดใหม่
Fox

1

J , 16 ไบต์

#:#.;.1~1,2=/\#:

ลองออนไลน์!

คำอธิบาย

#:#.;.1~1,2=/\#:  Input: integer n
              #:  Convert from decimal to list of binary digits
          2  \    For each overlapping sublist of size 2
           =/       Reduce using equals
        1,        Prepend 1
#:                Binary digits
    ;.1~          Partition those binary digits at the 1s in the previous list
  #.                Convert each partition from a list of binary digits to decimal

1

q / kdb +, 52 ไบต์

วิธีการแก้:

{2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}

ตัวอย่าง:

q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}0
,0
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}1
,1
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}3
1 1
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}8
2 0 0
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}10000
2 1 1 2 0 2 0 0 0
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}12914
1 2 2 1 1 2 2
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}371017
5 42 10 2 1
q){2 sv'cut[0,(&)(~)differ a]a:(63^(*)(&)a)_a:0b vs x}727429805944311
10 21 2 5 1 1 1 1 1 2 1 2 5 1 85 5 1 1 1 5 1 1

คำอธิบาย:

q ถูกตีความจากขวาไปซ้าย

แปลงอินพุตเป็นไบนารี่ตัดเลขศูนย์นำหน้าค้นหาดัชนีที่แตกต่างกันสลับกลับเพื่อรับดัชนีโดยแยกรายการบนดัชนีเหล่านี้กลับไปเป็นฐาน -10 ดูค่อนข้างหนักเมื่อเทียบกับโซลูชัน APL แม้ว่า ...

{2 sv'cut[0,where not differ a]a:(63^first where a)_a:0b vs x} / ungolfed solution
{                                                            } / lambda function
      cut[                    ]                                / cut a list at indices, cut[indices]list
                                                      0b vs x  / converts to 64bit binary representation
                                                    a:         / save as a
                                                   _           / drop 'n' elements from a
                                 (                )            / evaluate this
                                     first where a             / returns first occurance of true in list a
                                  63^                          / fill result with 63 if null (to handle input of 0)
                               a:                              / save as a, we've stripped off all the left-most 0s
                      differ a                                 / whether or not item in list a is different to previous
                  not                                          / the inversion of this result
            where                                              / these are the points where we have 00 or 11
          0,                                                   / add the first index too!
  2 sv'                                                        / 2 sv converts binary back to base-10, ' for each list

0

PHP, 147

$b=decbin($argv[1]);$a=[$t=$b[0]];$k=0;for($i=1;$i<strlen($b);$i++){$v=$b[$i];if($v==$t)$k++;$t=$v;$a[$k].=$v;}foreach($a as$c)echo bindec($c).' ';

จำเป็นต้องเพิ่มพื้นที่ว่างที่จุดสุดท้ายของเอาต์พุตเนื่องจากไม่มีข้อ จำกัด ประกาศจะปรากฏขึ้นสำหรับการเข้ารหัสระยะสั้น

เวอร์ชันที่ไม่ดี

$n=$argv[1];
$b=decbin($n);
$l=strlen($b);
$t=$b[0];
$a=[0=>$t];$k=0;
for($i=1;$i<$l;$i++){
    $v=$b[$i];
    if($v==$t){
        $k++;
    }
    $t=$v;$a[$k].=$v;    
}
foreach($a as $c){
    echo bindec($c).' ';
}

0

เรติน่า 60

+`(1+)\1
$1a
a1
1
(?<=(.))(?=\1)
¶
+`1(a*)\b
a$.1$*1;
a

;
1

ลองออนไลน์! หรือลองใช้รุ่นแก้ไขเล็กน้อยสำหรับกรณีทดสอบทั้งหมด (ที่มี I / O ทศนิยม)

น่าเสียดายที่การจับคู่ความยาวเป็นศูนย์ดูเหมือนจะมี "ด้าน" สองอันทำให้เกิดการทำซ้ำเมื่อใช้กับ regex จากสเตจที่สาม ค่าใช้จ่ายเพียงหนึ่งไบต์ว่า

รับอินพุตเป็น unary เอาต์พุตเป็น unary ไม่แน่ใจจริงๆเกี่ยวกับการใช้ค่า unary ที่แตกต่างกัน / ออก แต่จะประหยัด 4 ไบต์


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