İkili dosyayı alternatif alt bölümlere ayırın


30

Bu esinlenerek Binary Sigara Tekrarlayan - Problem 13 arasında HP CodeWars' son yarışma.

Diyelim ki rasgele bir ondalık sayı alalım.

727429805944311

ve ikili gösterime bakın:

10100101011001011111110011001011101010110111110111

Şimdi bu ikili gösterimi basamakların 0ve 1alternatiflerin bulunduğu alt dizilere ayırın.

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

Ve her bir sırayı tekrar ondalık basamağa dönüştürün.

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

Görev

Giriş olarak tek, pozitif bir tamsayı alın ve yukarıdaki işlemle elde edilen pozitif tamsayıların sırasını verin.

ayrıntılar

  • Giriş ve çıkış ondalık ya da tekdüze olmalıdır.
  • Çıktıdaki sayılar mantıklı, okunabilir bir şekilde ayrılmalı ve ondalık ya da tekdüze olmalıdır. Beyaz boşlukta kısıtlama yok. Geçerli çıktı stilleri: [1,2,3], 1 2 3, 1\n2\n3nerede \nvb edebi yeni satırlar vardır

Test durumları

 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

Ek not: çıktıdaki tüm sayılar (2^k-1)/3ya da biçiminde olmalıdır 2*(2^k-1)/3. Olduğunu, 0 1 2 5 10 21, 42, 85, 170, ..., hangi A000975 OEIS içinde.


@ DigitalTrauma: Hmmm ...... hayır, bunun meydan okuma ruhu içinde olduğunu sanmıyorum.
El'endia Starman

Tamam. |taccevabımda kalacak o zaman :)
Digital Trauma,

Yanıtlar:


11

Pyth, 17 16 bayt

Jakube sayesinde 1 bayt

iR2cJ.BQx1qVJ+dJ

gösteri

Güzel, zekice bir çözüm. Pyth'un daha az bilinen özelliklerini kullanır, x<int><list>ve 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
Eğer değiştirirseniz tJtarafından +dJKaldırabileceğiniz hM.
Jakube

@Jakube Güzel bir!
isaacg

7

Mathematica, 47 bayt

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

Ungolfed:

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

Split[list,f]bir listeyi birden fazla listeye böler, iff ave biff arasındaki pozisyonu f[a,b]geri döndürmez True.

FromDigits[n,2] => Fold[#+##&,n]alephalpha'dan temiz bir bahşiş .


7

Python, 86 bayt

Pyth’te korkunç bir şekilde aşıldığım için Python’da tekrar yapalım.

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

Burada dene!

açıklama

Girilen sayıyı nikili bir dizgeye dönüştürmekle başlarız . bin(n)[2:]Bununla ilgilenir. bin()Dize biçiminde döndürdüğü için bu dizenin ilk 2 karakterini atmamız gerekiyor 0b10101.
Daha sonra, altların sınırlarını tanımlamamız gerekir. Bu, dizgideki (?<=(.))(?=\1)sıfır uzunluktaki konumlarla aynı sayıdaki sola ve sağa uyan regex ile yapılabilir .
Tüm alt sıraların bir listesini elde etmenin en açık yolu, re.split()belirli bir regex üzerinde bir dize bölen kullanmaktır . Maalesef bu işlev sıfır uzunluktaki eşleşmelerde çalışmıyor. Ama neyse ki re.sub()öyle, biz sadece sıfır uzunluktaki eşleşmeleri boşluklarla değiştiririz ve bundan sonra ipi böldük.
O zaman bu alt dizilerin her birini bir ondalık sayı halinde ayrıştırmalıyız int(s,2)ve yapmalıyız.


4

Jöle, 12 bayt

BI¬-ẋż@BFṣ-Ḅ

Çevrimiçi deneyin! veya tüm test durumlarını doğrulayın .

Nasıl çalışır

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.

Kesinlikle 12 karakter ama 20 bayt. Yoksa CHAR_BIT >> 8 ile bir sistem mi kullanıyorsunuz?
James Youngman

1
@JamesYoungman Jelly, varsayılan olarak UTF-8 kullanmamaktadır. Aslında, her biri tek bir bayt olarak anladığı 256 karakterin her birini kodlayan kendi kod sayfasına sahiptir.
Dennis,

4

Bash + GNU yardımcı programları, 51

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

STDIN'den alınan giriş.

  • dc -e2o?p STDIN'den giriş tamsayısını okur ve temel 2 dizesini çıkarır
  • sed -r ':;s/(.)\1/\1 \1/;t' base 2 dizesini her ardışık basamak olan her yerde bir boşlukla böler
  • dc -e2i?fBir seferde bölünmüş ikiliyi okur, her bir parçayı yığının üzerine koyar, sonra ftüm dcyığını (çıkış numaraları ters sırayla) döker ...
  • ... tarafından düzeltildi tac.

4

JavaScript (ES6) 58 62 63

1 bayt düzenle thx @ETHproductions'ları düzenleme

4 bayt düzenle kaydedildi thx @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 ile iki bayt kurtarır mısın /(01)*0?|(10)*1?/g, yoksa bu bir şeyi mahveder mi?
ETHproductions

1
Ayrıca, x=>'0b'+x-0+' 'bir bayt kurtarmak için yapabileceğini düşünüyorum .
ETHProductions

@ETHproductions Ben kısa regexp denedim, hayır iyi :(. Diğer ipucu için Thx
edc65

Liderlik 1 baytlık bir cevabınız olduğunu söylüyor. Sanırım bunun yerine düzeltilmiş sayının (62) eski sayının (63) önünde olması gerekir.
Kyle Kanos

Bence regex /((.)(?!\2))*./gsize havalı 4 byte kazandırıyor.
Neil

3

Pyth, 26 bayt

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

Burada dene!

açıklama

iR2c: .BQ "(? <= (.)) (? = \\ 1)" d # Q = giriş numarası

     .BQ # Girişi ikiliye dönüştürür
    : "(? <= (.)) (? = \\ 1)" d #, alt dizinler arasına bir boşluk yerleştirin
   c # boşluklarda dize böl
iR2 #, her bir sırayı ondalık basamağa dönüştürür

Python'un split () işlevi sıfır uzunluklu eşleşmelerde bölünmediğinden, bu eşleşmeleri bir boşlukla değiştirip sonucu bunun üzerine bölmeliyim.


3

Pyth, 22 21 bayt

&Qu?q%G2H&
GH+yGHjQ2Z

Çevrimiçi deneyin: Gösteri

Pyth'ta gerçekten sıkıcı bir görev.

Açıklama:

&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 bayt

Kod:

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

Açıklama:

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

Çevrimiçi deneyin!

CP-1252 kodlamasını kullanır .


3

MATL , 18 17 bayt

YBTyd~Thhfd1wY{ZB

Çevrimiçi deneyin!

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 bayt

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

Nedenini bilmiyorum, ama bu Bash'de çalışmıyor.

Dennis'e 8 bayt için teşekkürler !


Bu forsözdizimi. ... Bekle, hayır yok formu?
Hesap MakinesiFeline

Bash'in aritmetik genişlemesi bir çıktı tabanı belirtmenize izin vermiyor. Xarg'lardan kurtulmak için kullanabilirsiniz 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 bayt

function d($i){for(;$d<$l=strlen($b=decbin($i));){$c.=$u=$b[$d];echo$u==$b[++$d]||$d==$l?bindec($c).$c=" ":"";}}
Parçalarına ayrıştırılmış görünüm
function d($i) {
  for ( ; $d < $l = strlen($b = decbin($i)); ) {
    $c .= $u = $b[$d];
    echo $u == $b[++$d] || $d == $l ? bindec($c) . $c = " "
                                    : "";
  }
}

Kullanın d(int)ve kapalıysanız, çıktı boşlukla ayrılmış bir echos dizesidir int.

Düzenlemeler:
-3:$b Tanımı strlen()çağrıya taşıdı .
-6: Kaldırılmış $cörnekleme.
-2: Sonunda birleştirme sorununu düzeltti.
-2: Tek hat için braket yokfor() .
-37: Tamamen revizyon. Going Arrayyerine tekrarlanan bir chunklets Array> - String-> Arrayçağrılar.
-1: Sinsi $csıfırlama.
+11: Hata düzeltme. Son yığın eksikti. Daha fazla yok.
-7: Hiç somutlaştırmaya gerek yok $dmu? Güzel.
-6: return -> echo.
-2: Çatırtı $c.
3:Üçlü, ilk aşkım.
-1: Sinsi sinsi $u.


Sana 2 bayt kaydedebilirsiniz düşünüyorum: function d($i){for(;$d<$l=strlen($b=decbin($i));print$u==$b[++$d]||$d==$l?bindec($c).$c=" ":"")$c.=$u=$b[$d];}.
Karadelik

2

Dışbükey 0.2+, 25 bayt

Dışbükey, CJam ve Golfscript'e dayanan, geliştirdiğim yeni bir dildir. Tercüman ve IDE burada bulunabilir . Giriş, komut satırı argümanlarına bir tamsayıdır. Bu CP-1252 kodlamasını kullanır .

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

Açıklama:

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 bayt

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

Dizeyi ayırmak için muhtemelen daha iyi bir düzenli ifade vardır. Regex konusunda uzman değilim ama denemeye devam edeceğim.

@FryAmTheEggman sayesinde -8 bayt


2

APL (APL) , 21 25 bayt

Şimdi de 0 işler.

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

Çevrimiçi deneyin!

2⊥⍣¯1⊢ Temel-2'ye dönüştürün, gerektiği kadar çok bit kullanın (litre-base-2 dönüşümünü ters çevirin)

{...}  Aşağıdaki anonim işlevi uygulayın

0:: Herhangi bir hata olursa:

  0 0 döndür

 şimdi dene:

  2=/⍵ Argümanın ikili eşitliği

  1, 1 hazırlamak

  ⍵⊂⍨ Bunu argümanı bölümlemek için kullanın (her biri için yeni bölüm başlar)

  2⊥¨ her birini taban-2'den dönüştür


1
Burada gerçekten yararlıdır. Bunu Jelly'e eklemeliyim.
Dennis,

@Dennis İki versiyonun farkında olun R←X⊂Y: ⎕ML<3(yani Dyalog tarzı) ile, X'deki her bir 1'e karşılık gelen sonuçta, X içindeki bir sonraki 1 (veya X'in son elemanı) olmadan önceki pozisyona yeni bir bölüm başlar. R'nin ardışık öğeleri ⎕ML=3(yani IBM stili) ile, X'deki karşılık gelen öğe öncekinden daha büyük olduğunda, sonuçta yeni bir bölüm başlatılır. X'teki 0'a karşılık gelen Y'deki öğeler sonuca dahil edilmez. Yani ⎕ML←1 ⋄ 1 0 0 1 0 1 1 ⊂ ⍳7eşittir ⎕ML←3⋄ 4 3 2 4 4 5 7 ⊂ `7`
Adám

2

Japt , 7 bayt

¤ò¥ mn2

Dene


açıklama

¤ò¥ mn2
           :Implicit input of integer U.
¤          :Convert to binary string.
 ò¥        :Split to an array by checking for equality.
    m      :Map over array.
     n2    :Convert to base-10 integer.

1

Python 3, 115 bayt

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]

açıklama

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 

Sonuçlar

>>> [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]

önceki çözüm (118 bayt)

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 bayt

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 listeyi hesaplayan adsız bir işlevdir.

Daha az golf oynadı:

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

Perl, 53 bayt

İçin +1 içerir -p

STDIN'deki sayı ile koş

perl -p alterbits.pl <<< 371017

alterbits.pl:

$_=sprintf"0b%b",$_;s/(.)\K(?=\1)/ 0b/g;s/\S+/$&/eeg

1

PowerShell, 103 bayt

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

Regex'de korkunç olduğum için, edc65'in cevabıyla aynı ifadeyi kullanıyorum .

Kesinlikle .NET tarafından ikili dosyadan dönüştürme yapmak için yapılan çağrıları ve düzenli ifadeleri eşleştirmek için .NET çağrısını yok edin. Aksi takdirde oldukça basit. Girişi alır $args[0], convertiçine besler, ikili bunu sMatches , sonuçta alır .Values, bir döngü yoluyla borular onları |%{...}ve convertbu değerler için geri s int. Çıktı boru hattında bırakılır ve örtük olarak yeni satırlarla yazdırılır.


Ekstra kredi için - (çoğunlukla) 126 baytlık regex olmayan bir sürüm

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

Tekrar giriş yaptık $args[0]ve convertonu ikili hale getirdik. İlk karakteri $lve kalan karakterleri de içine alarak karakter dizisi haline getirdik $r. Sonra göndeririz$r|%{...} , bir ikili xor sonucuna bağlı olarak bir boşlukla hazırlanmış karakterden veya sadece karakterden seçtiğimiz her yinelemenin seçtiği bir döngü üzerinden$l ve sonra ayarlanır.$l karaktere eşit . Bu, eğer aynı karaktere arka arkaya iki kez sahip olursak, aralarında boşluk bırakmamızı sağlar.

Döngünün çıktısı bir -joinaraya getirilir ve ilk karaktere $l, sonra -splitboşluklara eklenir (teknik olarak bir regex, ancak bunu saymayacağım). Daha sonra regex cevabı convertve çıkış tamsayıları ile aynı döngüyü yaparız .


1

Java 345 bayt

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;
  }
}

Ölçek

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

Çıktı

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
Programlama Bulmacaları ve Kod Golf'üne Hoşgeldiniz! Bu bir kod golf yarışması olduğundan, kodunuzu olabildiğince kısa tutmalısınız. İşte Java'da golf oynamak için bazı ipuçları. Sen boilerplate olmadan işlevini tanımlayarak başlayabilir packageve classve gereksiz boşluk kaldırarak. Herhangi bir sorunuz varsa bana bildirin!
Alex A.

1

Julia, 70 57 bayt

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

Bu bir tamsayıyı kabul eden ve bir tamsayı dizisi döndüren adsız bir işlevdir. Aramak için değişkene atayın.

Buradaki yaklaşım DenkerAffe'nin güzel Python'una benziyor cevabına . nKullanmanın ikili gösterimini elde ettik bin(n)ve elde edilen dizgiyi normal ifadenin tüm eşleşmelerinde böldük (?<=(.))(?=\1). Aslında sıfır uzunluklu bir eşleşme; (?<=(.))herhangi bir tek karakter bulabilen pozitif bir gözbebeğidir ve (?=\1)gözbebeği ile eşleşen karakteri bulan pozitif bir gözcüdür. Bu, bir sayının ikili göstergede kendisinin takip ettiği yerleri bulur. Sadece parseher biri üs 2'de bir tamsayı olarak mapve voila!


1

C 137 129 bayt

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);}

Giriş ve çıkış standart akışlardadır.


İhtiyacınız olduğunu sanmıyorum puts, kullanımı hoş olmasa da, teknik özellik izleyen bir yeni hat gerektirmez.
FryAmTheEggman

@FryAmTheEggman Tamamlanmamış bir son satır oluşturmamayı tercih ederim. Ancak bir baytın maliyeti için (yine de net bir indirim) Ayırıcıyı uzaydan yenisine değiştirebilirim.
Fox,

1

J , 16 bayt

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

Çevrimiçi deneyin!

açıklama

#:#.;.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 bayt

Çözüm:

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

Örnekler:

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

Açıklama:

q sağdan sola doğru yorumlanır.

Girdiyi ikili dosyaya dönüştürün, baştaki sıfırları kesin, farklı yerlerde indeksler bulun, bu indekslerdeki aynı, bölünmüş listenin tekrar baz-10'a döndüğü endeksleri elde edin. APL çözümüne kıyasla biraz ağır görünüyor ama ...

{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).' ';

Kısıtlama olmadıklarından, çıktının sonunda fazladan boşluk bırakmanız gerekir. Kısa kodlama için uyarılar görüntülenir.

Ungolfed versiyonu

$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

Retina, 60

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

;
1

Çevrimiçi deneyin! Veya biraz değiştirilmiş bir sürümü deneyin. tüm test durumları (ondalık G / Ç ile).

Maalesef, sıfır uzunluklu eşleşmelerin iki "tarafı" olduğu görülüyor ve üçüncü aşamadan regex ile kullanıldığında çoğaltmaya neden oluyor. Sadece bir byte olsa maliyeti.

Girdiyi unary olarak alır, unary olarak çıkar. Farklı giriş / çıkış unary değerleri kullandığınızdan emin değilim, ancak bu 4 bayttan tasarruf sağlar.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.