Rozkład binarny na przemienne podsekwencje

30

To był inspirowany przez Problem 13 - Non-Powtarzanie Binary z niedawnym konkursie HP CodeWars.

Powiedzmy, że weźmy losową liczbę dziesiętną

727429805944311

i spójrz na jego reprezentację binarną:

10100101011001011111110011001011101010110111110111

Teraz podziel binarną reprezentację na podsekwencje, gdzie cyfry 0i 1naprzemiennie.

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

I zamień każdą podsekwencję z powrotem na dziesiętną.

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

Zadanie

Weź jedną dodatnią liczbę całkowitą jako dane wejściowe i wyjściowe, a następnie wyślij sekwencję liczb całkowitych dodatnich uzyskanych w powyższym procesie.

Detale

  • Dane wejściowe i wyjściowe muszą być dziesiętne lub jednostkowe.
  • Liczby na wyjściu muszą być rozdzielone w rozsądny, czytelny dla człowieka sposób, i muszą być w postaci dziesiętnej lub jedności. Brak ograniczeń białych znaków. Prawidłowe style wyjściowe: [1,2,3], 1 2 3, 1\n2\n3gdzie \nsą literalne znaki nowej linii, itp

Przypadki testowe

 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

Uwaga dodatkowa: wszystkie liczby na wyjściu powinny mieć postać (2^k-1)/3lub 2*(2^k-1)/3. Oznacza to, że w OEIS 0 1 2 5 10 21, 42, 85, 170, ...jest A000975 .

El'endia Starman
źródło
@DigitalTrauma: Hmmm ...... nie, nie sądzę, że jest to zgodne z duchem wyzwania.
El'endia Starman
Dobrze. |tacpozostanie w mojej odpowiedzi :)
Cyfrowa trauma

Odpowiedzi:

11

Pyth, 17 16 bajtów

1 bajt dzięki Jakube

iR2cJ.BQx1qVJ+dJ

Demonstracja

Ładne, sprytne rozwiązanie. Używa mniej znanych funkcji Pytha, takich jak x<int><list>i 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.
isaacg
źródło
1
Jeśli zastąpić tJprzez +dJmożna usunąć hM.
Jakube,
@Jakube Nice one!
isaacg,
7

Mathematica, 47 bajtów

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

Nie golfowany:

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

Split[list,f]dzieli listę na wiele list, łamanie w pozycji między ai biff f[a,b]nie zwraca True.

FromDigits[n,2] => Fold[#+##&,n]to zgrabna wskazówka od alephalpha.

feersum
źródło
7

Python, 86 bajtów

Ponieważ zostałem okropnie wystrzelony w Pyth, zróbmy to jeszcze raz w Pythonie.

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

Wypróbuj tutaj!

Wyjaśnienie

Zaczynamy od konwersji liczby wejściowej nna ciąg binarny. bin(n)[2:]zajmuje się tym. Musimy odrzucić pierwsze 2 znaki tego ciągu, ponieważ bin()zwraca ciąg w formacie 0b10101.
Następnie musimy zidentyfikować granice podsekwencji. Można to zrobić za pomocą wyrażenia regularnego, (?<=(.))(?=\1)które pasuje do pozycji zerowej długości w łańcuchu, które mają tę samą liczbę po lewej i prawej stronie.
Oczywistym sposobem na uzyskanie listy wszystkich podsekwencji byłoby użycie, re.split()które dzieli ciąg znaków na określone wyrażenie regularne. Niestety ta funkcja nie działa dla dopasowań o zerowej długości. Ale na szczęście re.sub()tak jest, więc po prostu zamieniamy te dopasowania zerowej długości spacjami i dzielimy ciąg znaków na te później.
Następnie musimy tylko parsować każdy z tych podsekwencji z powrotem do liczby dziesiętnej za pomocą int(s,2)i gotowe.

Denker
źródło
4

Galaretka, 12 bajtów

BI¬-ẋż@BFṣ-Ḅ

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

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.
Dennis
źródło
Z pewnością 12 znaków, ale 20 bajtów. A może używasz systemu z CHAR_BIT >> 8?
James Youngman,
1
@JamesYoungman Jelly domyślnie nie używa UTF-8. W rzeczywistości ma własną stronę kodową, która koduje każdy z 256 znaków, które rozumie jako pojedynczy bajt.
Dennis
4

Narzędzia Bash + GNU, 51

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

Dane pobrane z STDIN.

  • dc -e2o?p odczytuje wejściową liczbę całkowitą ze STDIN i wyprowadza ciąg 2 bazowy
  • sed -r ':;s/(.)\1/\1 \1/;t' dzieli ciąg znaków base 2 spacją wszędzie tam, gdzie są takie same kolejne cyfry
  • dc -e2i?fodczytuje podzielony plik binarny za jednym razem, umieszczając każdą część na stosie, a następnie fzrzuca cały dcstos (liczby wyjściowe w odwrotnej kolejności) ...
  • ... co zostało poprawione przez tac.
Cyfrowa trauma
źródło
4

JavaScript (ES6) 58 62 63

Edytuj 1 bajt zapisany thx @ETHproductions

Edytuj 4 bajty zapisane 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>

edc65
źródło
Czy możesz zapisać dwa bajty za pomocą wyrażenia regularnego /(01)*0?|(10)*1?/g, czy może to coś zepsuło?
ETHproductions
1
Ponadto myślę, że możesz zrobić, x=>'0b'+x-0+' 'aby zapisać bajt.
ETHprodukcje
@ETHproductions Próbowałem krótszego wyrażenia regularnego, nic dobrego :(. Dziękuję za drugą wskazówkę
edc65
Tabela wyników mówi, że masz 1 bajtową odpowiedź. Zakładam, że to dlatego, że masz poprawioną liczbę (62) przed starą liczbą (63) zamiast po.
Kyle Kanos,
Myślę, że regex /((.)(?!\2))*./goszczędza ci fajne 4 bajty.
Neil
3

Pyth, 26 bajtów

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

Wypróbuj tutaj!

Wyjaśnienie

iR2c: .BQ "(? <= (.)) (? = \\ 1)" d # Q = numer wejściowy

     .BQ # Konwertuj dane wejściowe na binarne
    : "(? <= (.)) (? = \\ 1)" d # wstaw spację między podsekwencje
   c # ciąg podzielony na białe znaki
iR2 # zamienia każdą podsekwencję na dziesiętną

Ponieważ funkcja split () Pythona nie dzieli się na dopasowania o zerowej długości, muszę zamienić te dopasowania spacją i podzielić wynik na tym.

Denker
źródło
3

Pyth, 22 21 bajtów

&Qu?q%G2H&
GH+yGHjQ2Z

Wypróbuj online: demonstracja

Naprawdę żmudne zadanie w Pyth.

Wyjaśnienie:

&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
Jakube
źródło
3

05AB1E , 18 bajtów

Kod:

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

Wyjaśnienie:

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

Wypróbuj online!

Wykorzystuje kodowanie CP-1252 .

Adnan
źródło
3

MATL , 18 17 bajtów

YBTyd~Thhfd1wY{ZB

Wypróbuj online!

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
Luis Mendo
źródło
3

zsh, 67 63 55 bajtów

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

Nie wiem dlaczego, ale to nie działa w Bash.

Dzięki Dennis za 8 bajtów!

Klamka
źródło
To jest forskładnia. ... Czekaj, nie ma for?
CalculatorFeline,
Rozwinięcie arytmetyczne Basha nie pozwala określić bazy wyjściowej. Aby pozbyć się xargów, możesz użyć 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 112 bajtów

function d($i){for(;$d<$l=strlen($b=decbin($i));){$c.=$u=$b[$d];echo$u==$b[++$d]||$d==$l?bindec($c).$c=" ":"";}}
Widok rozstrzelony
function d($i) {
  for ( ; $d < $l = strlen($b = decbin($i)); ) {
    $c .= $u = $b[$d];
    echo $u == $b[++$d] || $d == $l ? bindec($c) . $c = " "
                                    : "";
  }
}

Użyj d(int)i jesteś wyłączony, wynik jest echociągiem ed intoddzielonym spacją.

Edycje:
-3: Przeniesiono $bdefinicję do strlen()wywołania.
-6: Usunięto $cinstancję.
-2: W końcu naprawiono problem konkatenacji.
-2: Brak nawiasów pojedynczej linii for().
-37: Całkowity przegląd. Iść z Arraykawałkami zamiast powtarzanych Array-> String-> Arraypołączeń.
-1: Podstępny $creset.
+11: Bugfix. Brakowało ostatniego kawałka. Już nie.
-7: Nie musisz $dw ogóle tworzyć instancji ? Miły.
-6: return -> echo.
-2: Chrupanie $c.
-3:Ternary, moja pierwsza miłość.
-1: Podstępny podstępny $u.

ricdesi
źródło
Myślę, że można zaoszczędzić 2 bajty: 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

Wypukły 0,2+, 25 bajtów

Convex to nowy język, który rozwijam, oparty w dużej mierze na CJam i Golfscript. Tłumacz i IDE można znaleźć tutaj . Dane wejściowe to liczba całkowita w argumentach wiersza poleceń. Wykorzystuje to kodowanie CP-1252 .

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

Wyjaśnienie:

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

Java 8, 127 119 bajtów

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

Prawdopodobnie istnieje lepsze wyrażenie regularne do podziału łańcucha. Nie jestem biegły w wyrażeniach regularnych, ale będę eksperymentował.

-8 bajtów dzięki @FryAmTheEggman

TNT
źródło
2

APL (APL) , 21 25 bajtów

Teraz obsługuje również 0.

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

Wypróbuj online!

2⊥⍣¯1⊢ przekonwertować na base-2, używając tyle bitów, ile potrzeba (lit. odwrócona konwersja z base-2)

{} Zastosuj następującą anonimową funkcję

0:: jeśli wystąpi jakikolwiek błąd:

  0 zwróć 0

 Spróbuj teraz:

  2=/⍵ parowa równość argumentu (zawiedzie jedną binarną reprezentację 0 o długości 0)

  1, prepend 1

  ⍵⊂⍨ użyj tego do podzielenia argumentu (zaczyna nową sekcję na każdym 1)

  2⊥¨ przekonwertować każdy z base-2

Adám
źródło
1
jest tu naprawdę przydatny. Powinienem dodać to do Galaretki.
Dennis
@Dennis Należy pamiętać o dwóch wersjach R←X⊂Y: Z ⎕ML<3(tj. Stylem Dyalog), nowa partycja jest uruchamiana w wyniku odpowiadającym każdemu 1 w X aż do pozycji przed następną 1 w X (lub ostatnim elementem X) kolejne elementy R. Z ⎕ML=3(tj. stylem IBM) nowa partycja jest uruchamiana w wyniku, gdy odpowiedni element w X jest większy niż poprzedni. Pozycje w Y odpowiadające 0 w X nie są uwzględniane w wyniku. ⎕ML←1 ⋄ 1 0 0 1 0 1 1 ⊂ ⍳7Jest to więc odpowiednik ⎕ML←3⋄ 4 3 2 4 4 5 7 ⊂ ⍳7`
Adám
2

Japt , 7 bajtów

¤ò¥ mn2

Sprawdź to


Wyjaśnienie

¤ò¥ 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.
Kudłaty
źródło
1

Python 3, 115 bajtów

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]

Wyjaśnienie

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 

Wyniki

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

poprzednie rozwiązanie (118 bajtów)

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')]
Erwan
źródło
1

Haskell, 147 , 145 bajtów

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 to nienazwana funkcja, która oblicza listę.

Mniej golfa:

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
Michael Klein
źródło
1

Perl, 53 bajty

Obejmuje +1 dla -p

Uruchom z numerem na STDIN

perl -p alterbits.pl <<< 371017

alterbits.pl:

$_=sprintf"0b%b",$_;s/(.)\K(?=\1)/ 0b/g;s/\S+/$&/eeg
Ton Hospel
źródło
1

PowerShell, 103 bajty

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

Ponieważ jestem okropny w wyrażeniach regularnych, używam tego samego wyrażenia, co odpowiedź edc65 .

Całkowicie zniszczone przez długie wywołania .NET w celu wykonania konwersji do / z pliku binarnego oraz wywołanie .NET w celu uzyskania dopasowania wyrażeń regularnych. W przeciwnym razie całkiem proste. Pobiera dane wejściowe $args[0], converts do pliku binarnego, wprowadza je do Matches, pobiera wynikowe .Values, przepuszcza je przez pętlę |%{...}i convertprzywraca te wartości int. Dane wyjściowe są pozostawione w potoku i domyślnie drukowane z nowymi liniami.


Dla dodatkowego kredytu - (przeważnie) wersja nieregexowa o wielkości 126 bajtów

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

Ponownie przyjmujemy dane wejściowe $args[0]i są convertone binarne. Przerzucamy ponownie jako tablicę znaków, przechowując pierwszy znak w, $la pozostałe znaki w $r. Następnie wysyłamy $rprzez pętlę, w |%{...}której każda iteracja, którą wybieramy, od znaku poprzedzonego spacją lub po prostu od znaku, w zależności od wyniku binarnego xor z $l, a następnie ustawiana na wartość $lrówną znakowi. To skutecznie zapewnia, że ​​jeśli mamy ten sam znak dwa razy z rzędu, wstawiamy odstęp między nimi.

Wyjście pętli jest -joinedytowane razem i dołączane do pierwszego znaku $l, a następnie -splitdo spacji (co jest technicznie wyrażeniem regularnym, ale nie zamierzam tego liczyć). Następnie wykonujemy tę samą pętlę, co wyrażenie regularne odpowiedzi converti wyjściowe liczby całkowite.

AdmBorkBork
źródło
1

Java 345 bajtów

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

Test

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

Wydajność

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
Jeff I
źródło
4
Witamy w Programowaniu Puzzle i Code Golf! Ponieważ są to zawody związane z golfem , powinieneś skrócić swój kod tak krótko, jak to możliwe. Oto kilka wskazówek dotyczących gry w golfa w Javie. Można zacząć od zdefiniowania funkcji bez boilerplate packagei classi usuwanie zbędnych spacji. Daj mi znać, jeśli masz jakieś pytania!
Alex A.
1

Julia, 70 57 bajtów

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

Jest to anonimowa funkcja, która przyjmuje liczbę całkowitą i zwraca tablicę liczb całkowitych. Aby go wywołać, przypisz go do zmiennej.

Podejście tutaj jest podobne do ładnej odpowiedzi Pythona na DenkerAffe . Otrzymujemy binarną reprezentację nużycia bin(n)i dzielimy wynikowy ciąg przy wszystkich dopasowaniach wyrażenia regularnego (?<=(.))(?=\1). To właściwie mecz o zerowej długości; (?<=(.))jest pozytywnym wyglądem, który znajduje dowolny pojedynczy znak, i (?=\1)jest pozytywnym spojrzeniem w przód, który znajduje dopasowaną postać w spojrzeniu. Lokalizuje to miejsca, w których liczba występuje po niej w reprezentacji binarnej. Tylko parsekażdy jako liczba całkowita w bazie 2 za pomocą mapi voila!

Alex A.
źródło
1

C, 137 129 bajtów

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

Wejścia i wyjścia są na standardowych strumieniach.

Lis
źródło
Nie wydaje mi się, żebyś potrzebował tego puts, chociaż jego użycie byłoby nieprzyjemne, specyfikacja nie wymaga końca nowej linii.
FryAmTheEggman
@FryAmTheEggman Wolałbym nie generować niekompletnej ostatniej linii. Ale za koszt jednego bajtu (wciąż redukcja netto) mogę zmienić separator z odstępu na nowy wiersz.
Fox
1

J , 16 bajtów

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

Wypróbuj online!

Wyjaśnienie

#:#.;.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
mile
źródło
1

q / kdb +, 52 bajty

Rozwiązanie:

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

Przykłady:

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

Wyjaśnienie:

q jest interpretowany od prawej do lewej.

Przesyłaj dane wejściowe na binarne, usuwaj początkowe zera, znajduj indeksy tam, gdzie są różne, odwróć, aby uzyskać indeksy tam, gdzie ta sama, podziel listę na tych indeksach, konwertuj z powrotem na base-10. Wygląda trochę ciężko w porównaniu do rozwiązania 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
Streetster
źródło
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).' ';

Muszą w końcu dodać dodatkowe miejsce na wyjściu, ponieważ nie stanowią ograniczenia. Powiadomienia są wyświetlane dla krótkiego kodowania.

Wersja bez golfa

$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).' ';
}
kuldeep.kamboj
źródło
0

Retina, 60

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

;
1

Wypróbuj online! Lub wypróbuj nieco zmodyfikowaną wersję dla wszystkich przypadków testowych (z dziesiętnym We / Wy).

Niestety dopasowania o zerowej długości wydają się mieć dwie „strony”, co powoduje duplikację, gdy używane jest z wyrażeniem regularnym z trzeciego etapu. Jednak kosztuje tylko jeden bajt.

Pobiera dane wejściowe jako jednoargumentowe, dane wyjściowe jako jedne. Nie jestem do końca pewien, czy użyjemy różnych wartości jednoargumentowych we / wy, ale zaoszczędziłoby to 4 bajty.

FryAmTheEggman
źródło