Descomponer binario en subsecuencias alternas

30

Esto se inspiró en el problema 13: binario no repetido de la reciente competencia de HP CodeWars.

Tomemos un número decimal aleatorio, digamos

727429805944311

y mira su representación binaria:

10100101011001011111110011001011101010110111110111

Ahora dividir esa representación binaria en subsecuencias donde los dígitos 0y 1alternos.

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

Y convertir cada subsecuencia nuevamente en decimal.

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

La tarea

Tome un solo entero positivo como entrada y salida de la secuencia de enteros positivos obtenida por el proceso anterior.

Detalles

  • La entrada y la salida deben estar en decimal o unario.
  • Los números en la salida deben estar separados de manera sensible y legible para los humanos, y deben estar en decimal o unario. No hay restricción en el espacio en blanco. Estilos de salida válidos: [1,2,3], 1 2 3, 1\n2\n3donde \nson literales saltos de línea, etc.

Casos de prueba

 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 los números en la salida deben ser de la forma (2^k-1)/3o 2*(2^k-1)/3. Es decir, 0 1 2 5 10 21, 42, 85, 170, ...que es A000975 en el OEIS.

El'endia Starman
fuente
@ Digital Trauma: Hmmm ... no, no creo que eso esté dentro del espíritu del desafío.
El'endia Starman
Okay. |tacpermanecerá en mi respuesta entonces :)
Digital Trauma

Respuestas:

11

Pyth, 17 16 bytes

1 byte gracias a Jakube

iR2cJ.BQx1qVJ+dJ

Demostración

Una buena solución inteligente. Utiliza algunas características menos conocidas de Pyth, como x<int><list>y 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
fuente
1
Si reemplaza tJpor +dJpuede eliminar hM.
Jakube
@Jakube ¡Buena!
isaacg
7

Mathematica, 47 bytes

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

Sin golf:

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

Split[list,f]divide una lista en varias listas, rompiendo en la posición entre ay bsi iff f[a,b]no regresa True.

FromDigits[n,2] => Fold[#+##&,n]es un buen consejo de alephalpha.

Feersum
fuente
7

Python, 86 bytes

Como me sobrepasaron horriblemente en Pyth, hagámoslo nuevamente en Python.

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

Pruébalo aquí!

Explicación

Comenzamos con la conversión del número de entrada nen una cadena binaria. bin(n)[2:]se encarga de eso. Necesitamos descartar los 2 primeros caracteres de esta cadena ya que bin()devuelve la cadena en el formato 0b10101.
A continuación, debemos identificar los bordes de las subsecuencias. Esto se puede hacer con la expresión regular (?<=(.))(?=\1)que coincide con las posiciones de longitud cero en la cadena que tienen el mismo número a la izquierda y a la derecha.
La forma obvia de obtener una lista de todas las subsecuencias sería utilizar re.split()la división de una cadena en una expresión regular determinada. Lamentablemente, esta función no funciona para coincidencias de longitud cero. Pero afortunadamente re.sub()sí, así que simplemente reemplazamos esas coincidencias de longitud cero con espacios y dividimos la cadena en esos después de eso.
Luego solo tenemos que analizar cada una de esas subsecuencias nuevamente en un número decimal con int(s,2)y listo.

Denker
fuente
4

Jalea, 12 bytes

BI¬-ẋż@BFṣ-Ḅ

Pruébalo en línea! o verificar todos los casos de prueba .

Cómo 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.
Dennis
fuente
Seguramente 12 caracteres pero 20 bytes. ¿O está utilizando un sistema con CHAR_BIT >> 8?
James Youngman
1
@JamesYoungman Jelly no usa UTF-8 por defecto. De hecho, tiene su propia página de códigos que codifica cada uno de los 256 caracteres que entiende como un solo byte cada uno.
Dennis
4

Bash + utilidades GNU, 51

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

Entrada tomada de STDIN.

  • dc -e2o?p lee el entero de entrada de STDIN y genera una cadena base 2
  • sed -r ':;s/(.)\1/\1 \1/;t' divide la cadena base 2 con un espacio en todas partes donde hay los mismos dígitos consecutivos
  • dc -e2i?flee el binario dividido de una vez, coloca cada parte en la pila, luego fvolca toda la dcpila (números de salida en orden inverso) ...
  • ... que es corregido por tac.
Trauma digital
fuente
4

JavaScript (ES6) 58 62 63

Editar 1 byte guardado thx @ETHproductions

Editar 4 bytes guardados gracias a @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
fuente
¿Podría guardar dos bytes con la expresión regular /(01)*0?|(10)*1?/g, o eso arruinaría algo?
ETHproductions
1
Además, creo que podría hacer x=>'0b'+x-0+' 'para guardar un byte.
ETHproductions
@ETHproductions Probé la expresión regular más corta, no es bueno :(. Gracias por la otra pista
edc65
El Leadboard dice que tiene una respuesta de 1 byte. Supongo que es porque tiene el número corregido (62) antes del número anterior (63) en lugar de después.
Kyle Kanos
Creo que la expresión regular /((.)(?!\2))*./gte ahorra 4 bytes geniales.
Neil
3

Pyth, 26 bytes

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

Pruébalo aquí!

Explicación

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

     .BQ # Convertir entrada a binario
    : "(? <= (.)) (? = \\ 1)" d # inserta un espacio en blanco entre las subsecuencias
   cadena dividida de c # en espacios en blanco
iR2 # convierte cada subsecuencia en decimal

Dado que la función split () de Python no se divide en coincidencias de longitud cero, tengo que reemplazar esas coincidencias con un espacio y dividir el resultado en eso.

Denker
fuente
3

Pyth, 22 21 bytes

&Qu?q%G2H&
GH+yGHjQ2Z

Pruébelo en línea: demostración

Realmente una tarea tediosa en Pyth.

Explicación:

&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
fuente
3

05AB1E , 18 bytes

Código:

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

Explicación:

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

Pruébalo en línea!

Utiliza la codificación CP-1252 .

Adnan
fuente
3

MATL , 18 17 bytes

YBTyd~Thhfd1wY{ZB

Pruébalo en línea!

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
fuente
3

zsh, 67 63 55 bytes

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

No sé por qué, pero esto no funciona en Bash.

¡Gracias a Dennis por 8 bytes!

Pomo de la puerta
fuente
Es la forsintaxis. ... Espera, ¿no for?
CalculatorFeline
La expansión aritmética de Bash no le permite especificar una base de salida. Para deshacerte de los xargs, puedes usar 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 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 en despiece ordenado
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)y ya está, la salida es una echocadena ed de ints separadas por un espacio.

Ediciones:
-3: Se movió la $bdefinición a la strlen()llamada.
-6: Se eliminó la $cinstanciación.
-2: Finalmente se solucionó el problema de concatenación.
-2: sin paréntesis para una sola línea for().
-37: Revisión total. Ir con Arraychunklets en lugar de repetidas Array-> String-> Arrayllamadas.
-1:$c reinicio furtivo .
+11: corrección de errores. Faltaba la parte final. No más.
-7: ¿No necesitas instanciar $den absoluto? Agradable.
-6: return -> echo.
-2: crujido $c.
-3:Ternario, mi primer amor.
-1: astuto astuto $u.

ricdesi
fuente
Creo que se puede ahorrar 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

Convexo 0.2+, 25 bytes

Convex es un nuevo lenguaje que estoy desarrollando que se basa en gran medida en CJam y Golfscript. El intérprete y el IDE se pueden encontrar aquí . La entrada es un número entero en los argumentos de la línea de comando. Esto usa la codificación CP-1252 .

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

Explicación:

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

Probablemente haya una mejor expresión regular para dividir la cadena. No soy experto en expresiones regulares, pero seguiré experimentando.

-8 bytes gracias a @FryAmTheEggman

TNT
fuente
2

APL (APL) , 21 25 bytes

Ahora maneja 0 también.

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

Pruébalo en línea!

2⊥⍣¯1⊢ convertir a base-2, utilizando tantos bits como sea necesario (literalmente, conversión inversa de base-2)

{... } aplica la siguiente función anónima

0:: Si ocurre algún error:

  0 volver 0

 ahora intenta:

  2=/⍵ igualdad por pares del argumento (fallará una representación binaria de longitud 0 de 0)

  1, anteponer 1

  ⍵⊂⍨ úselo para dividir el argumento (comienza una nueva sección en cada 1)

  2⊥¨ convertir cada uno de base-2

Adán
fuente
1
Es realmente útil aquí. Debería agregar eso a Jelly.
Dennis
@Dennis Tenga en cuenta las dos versiones de R←X⊂Y: Con ⎕ML<3(es decir, estilo Dyalog), se inicia una nueva partición en el resultado correspondiente a cada 1 en X hasta la posición anterior al siguiente 1 en X (o el último elemento de X) los elementos sucesivos de R. Con ⎕ML=3(es decir, estilo IBM), se inicia una nueva partición en el resultado siempre que el elemento correspondiente en X sea mayor que el anterior. Los elementos en Y correspondientes a 0 en X no se incluyen en el resultado. Entonces ⎕ML←1 ⋄ 1 0 0 1 0 1 1 ⊂ ⍳7es equivalente a ⎕ML←3⋄ 4 3 2 4 4 5 7 ⊂ ⍳7`
Adám
2

Japt , 7 bytes

¤ò¥ mn2

Pruébalo


Explicación

¤ò¥ 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.
Lanudo
fuente
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]

Explicación

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]

solución 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')]
Erwan
fuente
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 es una función sin nombre que calcula la lista.

Menos golfizado:

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
fuente
1

Perl, 53 bytes

Incluye +1 para -p

Ejecutar con el número en STDIN

perl -p alterbits.pl <<< 371017

alterbits.pl:

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

PowerShell, 103 bytes

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

Como soy horrible en expresiones regulares, estoy usando la misma expresión que la respuesta de edc65 .

Absolutamente destruido por las largas llamadas .NET para hacer conversión a / desde binario, y la llamada .NET para obtener las coincidencias de expresiones regulares. De lo contrario, bastante sencillo. Toma la entrada $args[0], convertla envía al binario, la introduce Matches, toma la resultante .Values, la canaliza a través de un bucle |%{...}y convertvuelve esos valores a int. La salida se deja en la tubería y se imprime implícitamente con nuevas líneas.


Para crédito adicional: una versión (en su mayoría) no regex a 126 bytes

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

Nuevamente tomamos input $args[0]y convertlo binario. Relanzamos como un conjunto de caracteres, almacenando el primer personaje $ly los caracteres restantes en $r. Luego enviamos a $rtravés de un bucle |%{...}donde cada iteración que seleccionamos, ya sea del carácter antepuesto con un espacio o solo el carácter, dependiendo del resultado de un binario xor con $l, y luego se establece $ligual al carácter. Esto efectivamente garantiza que si tenemos el mismo personaje dos veces seguidas, anteponemos un espacio entre ellos.

La salida del bucle se -joinedita y se agrega al primer carácter $l, luego -spliten espacios (que técnicamente es una expresión regular, pero no voy a contarlo). Luego hacemos el mismo bucle que la respuesta de expresiones regulares a convertlos enteros de salida.

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

Prueba

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

Salida

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
fuente
44
¡Bienvenido a Programming Puzzles & Code Golf! Dado que esta es una competencia de código de golf , debe hacer su código lo más corto posible. Aquí hay algunos consejos para jugar golf en Java. Puede empezar por la definición de su función sin el repetitivo packagey class, y la eliminación de espacios en blanco innecesarios. ¡Hazme saber si tienes alguna pregunta!
Alex A.
1

Julia, 70 57 bytes

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

Esta es una función anónima que acepta un número entero y devuelve una matriz entera. Para llamarlo, asígnelo a una variable.

El enfoque aquí es similar a la buena respuesta de DenkerAffe en Python . Obtenemos la representación binaria del nuso bin(n)y dividimos la cadena resultante en todas las coincidencias de la expresión regular (?<=(.))(?=\1). En realidad es un partido de longitud cero; (?<=(.))es una mirada hacia atrás positiva que encuentra cualquier carácter individual, y (?=\1)es una búsqueda hacia adelante positiva que encuentra el carácter coincidente en la mirada hacia atrás. Esto ubica los lugares donde un número es seguido por sí mismo en la representación binaria. ¡Solo parsecada uno como un entero en la base 2 usando mapy listo!

Alex A.
fuente
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);}

La entrada y la salida están en las transmisiones estándar.

zorro
fuente
No creo que necesite el puts, aunque sería desagradable de usar, la especificación no requiere una nueva línea final.
FryAmTheEggman
@FryAmTheEggman Prefiero no generar una última línea incompleta. Pero por el costo de un byte (todavía una reducción neta) puedo cambiar el separador del espacio a la nueva línea.
Fox
1

J , 16 bytes

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

Pruébalo en línea!

Explicación

#:#.;.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
millas
fuente
1

q / kdb +, 52 bytes

Solución:

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

Ejemplos:

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

Explicación:

q se interpreta de derecha a izquierda.

Transmita la entrada a binario, recorte los ceros a la izquierda, encuentre índices donde sea diferente, invierta para obtener índices donde sea el mismo, divida la lista en estos índices, vuelva a convertir a base-10. Sin embargo, parece un poco pesado en comparación con la solución 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
callejero
fuente
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).' ';

Es necesario poner espacio adicional al final de la salida ya que no hay restricción. Se muestran avisos para codificación corta.

Versión sin golf

$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
fuente
0

Retina, 60

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

;
1

Pruébalo en línea! O pruebe una versión ligeramente modificada para todos los casos de prueba (con E / S decimal).

Desafortunadamente, las coincidencias de longitud cero parecen tener dos "lados", causando duplicación cuando se usa con la expresión regular de la tercera etapa. Sin embargo, solo cuesta un byte.

Toma la entrada como unaria, la salida como unaria. No estoy realmente seguro de usar diferentes valores unarios de entrada / salida, pero eso ahorraría 4 bytes.

FryAmTheEggman
fuente