Convierte números a binarios ... pero también puedes usar dos

20

Basado en la notación "binaria, pero con dos" mencionada en este video de número numérico , escriba una función que tome un solo número como entrada y genere todas las variaciones de ese número en un sistema "binario" donde se permiten dos.

Reglas

  • El código solo debe ser una función / método, no un programa completo
  • La entrada es un número entero pasado como el único parámetro para la función
  • La salida es todas las variaciones válidas del número de entrada convertido a notación "binaria, pero con dos"
  • La salida es el valor de retorno de la función, pero puede estar en cualquier formato que sea conveniente siempre que sea obvio (por ejemplo, 3 ints, 3 cadenas, cadena delimitada por comas / espacios, matriz de entradas, etc.), el orden no es importante
  • En el caso improbable de que un idioma contenga una función incorporada para lograr el resultado, no se permite
  • El código más corto en bytes es el ganador

Explicación de la salida.

Por ejemplo, si se le pasa el número 9, puede convertirlo en binario como 1001, pero si permitió 2s en cada posición, también podría escribirlo como 201(es decir 2*4 + 0*2 + 1*1) o 121(es decir 1*4 + 2*2 + 1*1), como se muestra en esta tabla:

+----+----+----+----+
| 8s | 4s | 2s | 1s |
+----+----+----+----+
|  1 |  0 |  0 |  1 |
|  0 |  2 |  0 |  1 |
|  0 |  1 |  2 |  1 |
+----+----+----+----+

Entonces, si se aprueba 9, su función necesitaría devolver los tres números 1001, 201y 121.

Formato y el orden son irrelevantes, tanto tiempo como es obvio (es decir [121,201,1001], "0201 0121 1001", ("1001","121","201")son resultados válidos cuando dada una entrada de 9).

Ejemplos

  • 2 => 10, 2
  • 9 => 1001, 201, 121
  • 10 => 1010, 210, 202, 1002, 122
  • 23 => 2111, 10111
  • 37 => 100101, 20101, 100021, 20021, 12101, 12021, 11221
Alconja
fuente
1
¿Dos? En binario? ¿Es esto computación cuántica?
Matthew Roh

Respuestas:

10

GolfScript (25 bytes) / CJam ( 19 17 bytes)

GolfScript:

{:^.*,{3base}%{2base^=},}

Esto crea una función anónima (ver meta discusión sobre la permisibilidad de las funciones anónimas ).

Demostración en línea

Una traducción directa a CJam es (gracias a Martin Büttner por afeitar un par de caracteres)

{:X_*,3fb{2bX=},}

Disección

{             # Function boilerplate
  :^          # Store parameter as variable ^
  .*          # Square parameter - see detailed explanation below
  ,{3base}%   # Produce an array of 0 to ^*^-1 in ternary
  {2base^=},  # Filter to those which evaluate to ^ in binary
}

La razón de la operación de cuadratura es que necesitamos iterar hasta el mayor valor posible cuya representación ternaria, interpretada en binario, sea igual a ^. Desde entonces 2 = 10, la representación binaria "normal" de ^es la que importa. Si convertimos eso a ternario, encontramos que los "peores" casos son poderes de 2. Un enfoque óptimo sería llevar el argumento al poder de ln 3/ln 2 ~= 1.585, pero la cuadratura es mucho más corta.

Peter Taylor
fuente
Apuesto a que una traducción de CJam será mucho más pequeña.
Optimizador
1
@Optimizer adelante ;-)
John Dvorak
GolfScript? hombre, soy un novato
pythonian29033
8

Python 2 (59 bytes)

S=lambda n,B="":[B][n:]or~n%2*S(n/2-1,"2"+B)+S(n/2,`n&1`+B)

(Muchas gracias a @grc, @xnor y @PeterTaylor por ayudar en el chat)

Recurrencia simple, llamada con S(23)o similar.

Explicación

La idea general es que si nla expansión binaria termina en a 1, entonces cualquier expansión pseudobinaria ("binaria, pero con dos") también debe terminar con a 1. De lo contrario, podría terminar con 0o 2.

Por lo tanto, miramos el último bit de n, dividir y ramificar en consecuencia.

Disección

S=lambda n,B="":           # Lambda expression
[B][n:]or                  # Short circuit, return [B] if n==0 else what follows
~n%2*                      # Keep next list result if n is even else turn into []
S(n/2-1,"2"+B)             # Add a "2" to B, recurse
+
S(n/2,`n&1`+B)             # Add "0" or "1" to B depending on n's last bit, recurse

Variables:

  • n: El número que queremos encontrar expansiones pseudobinarias de
  • B: Una cadena pseudobinaria que se construye de derecha a izquierda
Sp3000
fuente
5

Bash + coreutils, 77

f()(seq `dc -e2o$1p`|sed '/[3-9]/d;s/.*/&n9P2i&pAi/'|dc|grep -Po ".*(?= $1)")

(Ese es un TABpersonaje en la expresión grep).

Esto está doblando un poco esta regla:

"En el improbable caso de que un idioma contenga una función incorporada para lograr el resultado, no se permite"

Resulta que dctiene el reverso de lo que necesitamos incorporado. Por ejemplo, si establecemos la base de entrada en 2 e ingresamos un número binario con dos, lo analizará correctamente. (Del mismo modo, si el modo de entrada es base 10, AF se analiza como "dígitos" decimales 10-15).

seqcrea una lista de todos los números decimales hasta la representación binaria estándar de n, analizada como decimal. Luego, todos los números que contienen algo distinto de {0,1,2} se filtran. Luego dcanaliza los números restantes como binarios para ver cuáles evalúan de nuevo a n.

Las funciones Bash solo pueden "devolver" enteros escalares 0-255. Así que me tomo la libertad de imprimir la lista en STDOUT como mi forma de "regresar". Esto es idiomático para los scripts de shell.

Salida:

$ f 2
2   
10  
$ f 9
121 
201 
1001    
$
Trauma digital
fuente
4

Haskell, 82

t n=[dropWhile(==0)s|s<-mapM(\_->[0..2])[0..n],n==sum[2^(n-i)*v|(i,v)<-zip[0..]s]]

Esta es solo una solución de fuerza bruta. es muy ineficiente porque se espera que supere las 3 ^ n posibilidades.

orgulloso Haskeller
fuente
3

Jelly , 10 bytes, desafío de fechas posteriores al idioma

ṗ@3Ḷ¤Ḅ=¥Ðf

Pruébalo en línea!

Una solución de fuerza bruta de hasta un número de hiperbits igual a la entrada (este formato se conoce como "hiperbinario"). Como tal, es increíblemente ineficiente, ejecutándose en O (3 n ).

Explicación

ṗ@3Ḷ¤Ḅ=¥Ðf
ṗ@            Construct all lists with the given length, and elements taken from
  3Ḷ¤         the list [0,1,2]
        Ðf    then take only those elements which
     Ḅ=¥      when interpreted as binary, equal {the original number}

fuente
2

PHP, 138 bytes

function p($v,$i=0,$r=""){global$a;if($v==0)$a[]=$r?:0;elseif($v>0)for(;$l<3;)p($v-2**$i*$l,$i+1,+$l++.$r);}p($argv[1]);echo join(",",$a);

Descompostura

function p($v,$i=0,$r=""){
    global$a;
    if($v==0)$a[]=$r?:0;  # fill result array
    elseif($v>0) # make permutations
        for(;$l<3;)
            p($v-2**$i*$l,$i+1,+$l++.$r); #recursive
}
p($argv[1]);
echo join(",",$a); # Output
Jörg Hülsermann
fuente
1

C ++, 159 bytes

void c(int x,string r){int i,t=0,s=r.size();if(s<8){if(r[0]>48){for(i=0;i<s;i++)t+=(r[s-i-1]-48)*1<<i;if(t==x)cout<<r<<" ";}for(char n=48;n<51;n++)c(x,r+n);}}

Pruébalo aquí

Johan du Toit
fuente
1

k, 21 bytes

Utiliza el mismo método que la respuesta Golfscript de Peter Taylor

{X@&x=2/:'X:3\:'!x*x}

Ejemplos:

k) {X@&x=2/:'X:3\:'!x*x}9
(1 2 1;2 0 1;1 0 0 1)
k) {X@&x=2/:'X:3\:'!x*x}10
(1 2 2;2 0 2;2 1 0;1 0 0 2;1 0 1 0)
skeevey
fuente