Decompor o binário em subsequências alternadas


30

Isso foi inspirado no Problema 13 - Binário Não Repetitivo da recente concorrência do HP CodeWars.

Vamos pegar um número decimal aleatório, digamos

727429805944311

e veja sua representação binária:

10100101011001011111110011001011101010110111110111

Agora divida essa representação binária em subsequências onde os dígitos 0e 1alternam.

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

E converta cada subsequência novamente em decimal.

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

A tarefa

Pegue um inteiro único positivo como entrada e faça a saída da sequência de números inteiros positivos obtida pelo processo acima.

Detalhes

  • A entrada e a saída devem estar em decimal ou unário.
  • Os números na saída devem ser separados de maneira sensível e legível por humanos, e devem estar em decimal ou unário. Nenhuma restrição no espaço em branco. Estilos de saída válidos: [1,2,3], 1 2 3, 1\n2\n3onde \nsão novas linhas literais, etc.

Casos de teste

 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

Nota adicional: todos os números na saída devem estar no formato (2^k-1)/3ou 2*(2^k-1)/3. Ou seja, 0 1 2 5 10 21, 42, 85, 170, ...que é A000975 no OEIS.


@DigitalTrauma: Hmmm ...... não, não acho que esteja dentro do espírito do desafio.
El'endia Starman 12/03/16

Está bem. |tacpermanecerá na minha resposta então :)
Digital Trauma

Respostas:


11

Pitão, 17 16 bytes

1 byte graças a Jakube

iR2cJ.BQx1qVJ+dJ

Demonstração

Uma solução agradável e inteligente. Usa alguns recursos menos conhecidos do Pyth, como x<int><list>e 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
Se você substituir tJpor +dJvocê pode remover hM.
Jakube 11/03

@Jakube Nice one!
Isaacg

7

Mathematica, 47 bytes

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

Ungolfed:

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

Split[list,f]divide uma lista em várias listas, quebrando na posição entre ae bse f[a,b]não retornar True.

FromDigits[n,2] => Fold[#+##&,n]é uma dica legal de alefalpha.


7

Python, 86 bytes

Desde que fui terrivelmente derrotado em Pyth, vamos fazê-lo novamente em Python.

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

Experimente aqui!

Explicação

Começamos com a conversão do número de entrada nem uma string binária. bin(n)[2:]cuida disso. Precisamos descartar os 2 primeiros caracteres dessa sequência, pois ela bin()retorna no formato 0b10101.
Em seguida, precisamos identificar as bordas das subsequências. Isso pode ser feito com o regex (?<=(.))(?=\1)que corresponde às posições de comprimento zero na string que têm o mesmo número à esquerda e à direita.
A maneira óbvia de obter uma lista de todas as subsequências seria usar o re.split()que divide uma string em um determinado regex. Infelizmente, esta função não funciona para correspondências de tamanho zero. Mas, felizmente re.sub(), substituímos essas correspondências de comprimento zero por espaços e dividimos a sequência naquelas depois disso.
Depois, basta analisar cada uma dessas subsequências em um número decimal com int(s,2)e pronto.


4

Gelatina, 12 bytes

BI¬-ẋż@BFṣ-Ḅ

Experimente online! ou verifique todos os casos de teste .

Como funciona

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.

Certamente 12 caracteres, mas 20 bytes. Ou você está usando um sistema com CHAR_BIT >> 8?
James Youngman 12/03

1
@JamesYoungman Jelly não usa UTF-8 por padrão. De fato, ele possui sua própria página de códigos que codifica cada um dos 256 caracteres que entende como um único byte cada.
Dennis

4

Utilitários Bash + GNU, 51

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

Entrada retirada do STDIN.

  • dc -e2o?p lê o número inteiro de entrada de STDIN e gera uma string de base 2
  • sed -r ':;s/(.)\1/\1 \1/;t' divide a string da base 2 com um espaço em todos os lugares onde há os mesmos dígitos consecutivos
  • dc -e2i?flê o binário dividido de uma só vez, colocando cada parte na pilha e depois fdespeja toda a dcpilha (números de saída na ordem inversa) ...
  • ... que é corrigido por tac.

4

JavaScript (ES6) 58 62 63

Editar 1 byte salvo thx @ETHproductions

Editar 4 bytes salvos 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>


Você poderia salvar dois bytes com o regex /(01)*0?|(10)*1?/gou isso atrapalhava alguma coisa?
ETHproductions

1
Além disso, acho que você poderia fazer x=>'0b'+x-0+' 'para salvar um byte.
ETHproductions

@ETHproductions Eu tentei o regexp mais curto, não é bom :( Thx para a outra pista.
edc65

O Leadboard diz que você tem uma resposta de 1 byte. Presumo que é porque você tem o número corrigido (62) antes do número antigo (63) em vez de depois.
Kyle Kanos

Eu acho que o regex /((.)(?!\2))*./gpoupa 4 bytes legais.
Neil

3

Pitão, 26 bytes

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

Experimente aqui!

Explicação

iR2c: .BQ "(? <= (.)) (? = \\ 1)" d # Q = número de entrada

     .BQ # Converter entrada em binário
    : "(? <= (.)) (? = \\ 1)" d # insere um espaço em branco entre as subsequências
   c # dividir string nos espaços em branco
iR2 # converte cada subsequência em decimal

Como a função split () do Python não se divide em correspondências de comprimento zero, eu tenho que substituir essas correspondências por um espaço e dividir o resultado nisso.


3

Pitão, 22 21 bytes

&Qu?q%G2H&
GH+yGHjQ2Z

Experimente online: Demonstração

Realmente uma tarefa tediosa em Pyth.

Explicação:

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

Código:

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

Explicação:

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

Experimente online!

Usa a codificação CP-1252 .


3

MATL , 18 17 bytes

YBTyd~Thhfd1wY{ZB

Experimente 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

3

zsh, 67 63 55 bytes

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

Não sei por que, mas isso não funciona no Bash.

Agradecimentos a Dennis por 8 bytes!


É a forsintaxe. ... espera, não foré?
CalculatorFeline

A expansão aritmética do Bash não permite especificar uma base de saída. Para se livrar do xargs, você pode usar for i in `grep -oP '1?(01)*0?'<<<$[[##2]$1]`;<<<$[2#$i].
1111 Dennis

2

PHP, 171 168 162 160 158 121 120 131 124 118 116 113 112 bytes

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

Use d(int)e pronto, a saída é uma echosequência ed de ints separada por um espaço.

Edições:
-3:$b definição movida para a strlen()chamada.
-6: Instanciação removida $c.
-2: finalmente foi corrigido o problema de concatenação.
-2: sem colchetes para linha única for().
-37: Revisão total. Indo com Arraychunklets em vez de repetidas Array-> String-> Arraychamadas.
-1:$c Redefinição sorrateira .
+11: Correção de bugs. Faltava parte final. Não mais.
-7: Não precisa instanciar $dnada? Agradável.
-6: return -> echo.
-2: Trituração $c.
-3:Ternário, meu primeiro amor.
-1: sorrateira sorrateira $u.


Eu acho que você pode salvar 2 bytes: 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 convexo, 25 bytes

Convexo é uma nova linguagem que estou desenvolvendo que é fortemente baseada em CJam e Golfscript. O intérprete e o IDE podem ser encontrados aqui . A entrada é um número inteiro nos argumentos da linha de comandos. Isso usa a codificação CP-1252 .

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

Explicação:

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 bytes

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

Provavelmente existe uma expressão regular melhor por aí para dividir a string. Não sou proficiente em regex, mas continuarei experimentando.

-8 bytes graças a @FryAmTheEggman


2

APL (APL) , 21 25 bytes

Agora lida com 0 também.

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

Experimente online!

2⊥⍣¯1⊢ converter para base-2, usando quantos bits forem necessários (conversão inversa a partir da base-2)

{} Aplique a seguinte função anônima

0:: se ocorrer algum erro:

  0 retornar 0

 agora tente:

  2=/⍵ igualdade entre pares do argumento (falhará na representação binária de 0 e comprimento 0)

  1, anexar 1

  ⍵⊂⍨ use isso para particionar o argumento (inicia uma nova seção em cada 1)

  2⊥¨ converter cada um da base-2


1
é realmente útil aqui. Eu deveria acrescentar isso ao Jelly.
Dennis

@Dennis Esteja ciente das duas versões de R←X⊂Y: Com ⎕ML<3(por exemplo, estilo Dyalog), uma nova partição é iniciada no resultado correspondente a cada 1 em X até a posição antes que o próximo 1 em X (ou o último elemento de X) se torne os itens sucessivos de R. Com ⎕ML=3(isto é, estilo IBM), uma nova partição é iniciada no resultado sempre que o elemento correspondente em X for maior que o anterior. Os itens em Y correspondentes a 0s em X não são incluídos no resultado. Assim, ⎕ML←1 ⋄ 1 0 0 1 0 1 1 ⊂ ⍳7é equivalente a ⎕ML←3⋄ 4 3 2 4 4 5 7 ⊂ ⍳7`
Adám

2

Japonês , 7 bytes

¤ò¥ mn2

Teste-o


Explicação

¤ò¥ 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 bytes

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]

Explicação

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 

Resultados

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

solução anterior (118 bytes)

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 é uma função sem nome que calcula a lista.

Menos golfe:

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 bytes

Inclui +1 para -p

Corra com o número em STDIN

perl -p alterbits.pl <<< 371017

alterbits.pl:

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

1

PowerShell, 103 bytes

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

Como sou péssimo em regex, estou usando a mesma expressão da resposta de edc65 .

Absolutamente destruído pelas chamadas longas do .NET para fazer a conversão de / para o binário e a chamada .NET para obter as correspondências de expressão regular. Caso contrário, bem direto. Leva a entrada $args[0], converts para binária, alimenta Matches, pega os .Values resultantes , canaliza-os através de um loop |%{...}e converts esses valores de volta para int. A saída é deixada no pipeline e implicitamente impressa com novas linhas.


Para crédito extra - uma versão não regex (principalmente) a 126 bytes

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

Mais uma vez, consideramos a entrada $args[0]e converta binária. Relançamos como um conjunto de caracteres, armazenando o primeiro caractere $le os caracteres restantes $r. Em seguida, enviamos $ratravés de um loop |%{...}onde todas as iterações que selecionamos do caractere precedido de um espaço ou apenas do caractere, dependendo do resultado de um xor binário com $le, em seguida, definimos$l para o caractere. Isso efetivamente garante que, se tivermos o mesmo caractere duas vezes seguidas, colocaremos um espaço entre eles.

A saída do loop é -joineditada em conjunto e anexada ao primeiro caractere $l, depois -splitnos espaços (o que é tecnicamente um regex, mas não vou contar). Em seguida, fazemos o mesmo loop que o regex responde converte gera números inteiros.


1

Java 345 bytes

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

Teste

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

Saída

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
Bem-vindo à programação de quebra-cabeças e código de golfe! Como esta é uma competição de código-golfe , você deve tornar seu código o mais curto possível. Aqui estão algumas dicas para jogar golfe em Java. Você pode começar definindo sua função sem o clichê packagee class, e removendo espaços em branco desnecessários. Deixe-me saber se você tiver alguma dúvida!
Alex A.

1

Julia, 70 57 bytes

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

Esta é uma função anônima que aceita um número inteiro e retorna uma matriz inteira. Para chamá-lo, atribua-o a uma variável.

A abordagem aqui é semelhante à boa resposta Python da DenkerAffe . Obtemos a representação binária do nuso bin(n)e dividimos a sequência resultante em todas as correspondências da expressão regular (?<=(.))(?=\1). Na verdade, é uma partida de comprimento zero; (?<=(.))é uma aparência positiva que encontra qualquer caractere único e (?=\1)uma aparência positiva que encontra o caractere correspondente na aparência. Isso localiza os lugares onde um número é seguido por ele próprio na representação binária. Apenas parsecada um como um número inteiro na base 2 usando mape pronto!


1

C, 137 129 bytes

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

Entrada e saída estão nos fluxos padrão.


Eu não acho que você precise puts, mesmo que seja desagradável de usar, a especificação não exige uma nova linha à direita.
FryAmTheEggman 15/03

@FryAmTheEggman Prefiro não gerar uma última linha incompleta. Mas, pelo custo de um byte (ainda uma redução líquida), posso alterar o separador de espaço para nova linha.
Fox

1

J , 16 bytes

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

Experimente online!

Explicação

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

Solução:

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

Exemplos:

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

Explicação:

q é interpretado da direita para a esquerda.

Converta a entrada em binário, apare os zeros à esquerda, encontre os índices onde forem diferentes, inverta para obter os índices nos mesmos, divida a lista nesses índices e converta de volta à base 10. Parece um pouco pesado em comparação com a solução APL embora ...

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

Precisa colocar espaço extra no final da saída, pois não há restrição. As notificações são exibidas para codificação curta.

Versão ungolfed

$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

Experimente online! Ou tente uma versão ligeiramente modificada para todos os casos de teste (com E / S decimal).

Infelizmente, correspondências de comprimento zero parecem ter dois "lados", causando duplicação quando usadas com a regex do terceiro estágio. Custa apenas um byte.

Pega a entrada como unária, e a saída como unária. Não tenho certeza sobre o uso de valores unários diferentes de entrada / saída, mas isso economizaria 4 bytes.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.