¡Planta un bosque binario!

24

Inspirado en A014486 .

Reto

Dada una entrada entera en la base 10, construya una representación para el bosque binario correspondiente a la entrada. Las representaciones incluyen, entre otras, matrices y cadenas anidadas.

¿Cómo?

Convierta la entrada a binario. 1s representan ramas y 0s representan hojas.

Para que esto sea más fácil de entender, usemos 834(1101000010 en binario) como ejemplo.


Comenzamos con el primer dígito. El primer dígito es a 1, por lo que dibujamos ramas:

\ /
 1

o como una matriz, {{1}}


El siguiente dígito es 1, por lo que dibujamos más ramas (vamos de izquierda a derecha):

\ /
 1
  \ /
    1

o como una matriz, {{1, {1}}}


El siguiente dígito es 0, así que colocamos una hoja:

0 0
 \ /
  1
   \ /
     1

o como una matriz, {{1, {1, 0}}}


El siguiente dígito es un 1, así que colocamos una rama:

     \ /
0 1
 \ /
   1
      \ /
         1

o como una matriz, {{1, {1, 0, {1}}}}


Repitiendo el proceso, obtenemos el siguiente árbol después del octavo dígito:

    0 0
     \ /
0 1
 \ /
   1 0
      \ /
         1

o como una matriz, {{1, {1, 0, {1, 0, 0}}, 0}}


Para los dígitos restantes, dibujamos más árboles:

El noveno dígito es un 0, así que colocamos una hoja (¡aww, es un brote joven!)

    0 0
     \ /
0 1
 \ /
   1 0
      \ /
         1 0

o como una matriz, {{1, {1, 0, {1, 0, 0}}, 0}, 0}


Cuando usamos todos los dígitos, terminamos con esto:

    0 0
     \ /
0 1
 \ /
   1 0 0
      \ / \ /
         1 0 1

o como una matriz, {{1, {1, 0, {1, 0, 0}}, 0}, 0, {1, 0}}


Eso se ve raro, así que rellenamos un cero para completar el árbol:

    0 0
     \ /
0 1
 \ /
   1 0 0 0
      \ / \ /
         1 0 1

o como una matriz, {{1, {1, 0, {1, 0, 0}}, 0}, 0, {1, 0, 0}}

Tenga en cuenta que al aplanar la matriz se obtiene el número original en binario, pero con un cero rellenado.

Criterios

  • La salida debe mostrar claramente la separación de los árboles y las ramas (si no es una matriz anidada, explique su formato de salida).
  • La extracción de todos los dígitos de la salida debe ser idéntica a la representación binaria de la entrada (con los cero rellenados del proceso anterior).

Casos de prueba

El resultado puede diferir siempre que cumpla con los criterios.

0 -> {0}
1 -> {{1, 0, 0}}
44 -> {{1, 0, {1, {1, 0, 0}, 0}}}
63 -> {{1, {1, {1, {1, {1, {1, 0, 0}, 0}, 0}, 0}, 0}, 0}}
404 -> {{1, {1, 0, 0}, {1, 0, {1, 0, 0}}}}
1337 -> {{1, 0, {1, 0, 0}}, {1, {1, {1, 0, 0}, {1, 0, 0}}, 0}}

Tanteo

Este es el , por lo que gana los bytes más bajos.

JungHwan Min
fuente
55
Me gustaría evitar el uso de bonos - por lo general no mejora el desafío.
Sanchises
1
@Sanchises Agregué el bono para ver las respuestas con la visualización ... ¿De qué otra forma podría alentar a las personas a intentar hacer una visualización como salida?
JungHwan Min
44
(re su comentario) ¿Lo requiere?
msh210
1
@JungHwanMin Mira lo que he vinculado con más detalle (especialmente los comentarios); o, en la misma Meta pregunta, esta respuesta. Su pregunta actual requiere carteles para crear 2 ^ 2 = 4 programas y calcular la puntuación de cada programa, antes de enviar el mejor programa de puntuación. Exígelo cuando creas que es un desafío mejor o retíralo si crees que es un desafío peor.
Sanchises
2
@JungHwanMin Bastante justo. Deben jugar golf 3 programas y calcular cada puntaje individual antes de enviar una respuesta. Lo que tienes aquí son tres desafíos envueltos en uno. Recomendaría publicar la visualización como un desafío separado.
Sanchises

Respuestas:

2

JavaScript (ES6), 96 89 80 79 74 73 bytes

f=($,_=~Math.log2($))=>0>_?[(g=f=>$&1<<~_++&&[1,g(),g()])(),...f($,_)]:[]
<input type="number" value="1337" oninput="document.querySelector('#x').innerHTML=JSON.stringify(f(+this.value))"/><br/><pre id="x"></pre>

Define una función fque devuelve una matriz anidada. El código HTML es solo para probar.

PurkkaKoodari
fuente
Por un segundo estuve pensando "¿qué diablos está $&haciendo sin .replace?" : P
ETHproductions
@ETHproductions Me aburrí un poco y ofusqué los nombres de las variables. Lástima que JS no permita otros símbolos únicos: D
PurkkaKoodari
9

Befunge, 138 117 104 bytes

p&1v
%2:_v#:/2p9p00+1:g00
3\9g<>$\:!v!:<
9g!v ^,"}"_1-\1-:
"0"_2\"1{",,:|:,
`#@_\:#v_"}",>$\:8
,"0":-1<^

Pruébalo en línea!

Explicación

La línea 1 lee un número de stdin, y la línea 2 convierte ese número en una secuencia binaria que almacena en el campo de juego en la línea 10. Las líneas 3 a 5 luego iteran sobre esos dígitos binarios, generando la representación de árbol apropiada a medida que se procesa cada dígito. La pila Befunge se usa para realizar un seguimiento de la profundidad en el árbol y cuánto espacio de hoja queda en cada nivel para que sepamos cuándo crear una nueva rama. Las líneas 6 y 7 manejan el 0relleno final para llenar las hojas vacías.

Para jugar golf tanto como sea posible, eliminé las comas de la salida, así como los soportes externos extraños. Esto todavía no ha superado la solución de Mathematica, pero ha sido divertido intentarlo.

Si desea ver cómo se veía con el formato de salida detallado original, guardé una versión anterior del código aquí (131 bytes).

James Holderness
fuente
1
(esto no tiene suficientes votos a favor: D)
Addison Crump
4

Mathematica, 167161 bytes

b=Append;a=If[#&@@#>0,a[Rest@#~b~0,a[#,#3[#,{1,#4,#2},##5]&,#3,#2,##4]&,#2,##3],
#2[Rest@#~b~0,0,##3]]&;a[#~IntegerDigits~2,If[c=#3~b~#2;Tr@#>0,a[#,#0,c],c]&,
{}]&

Función anónima. Toma un número como entrada y devuelve una lista arbitrariamente anidada de números como salida. Saltos de línea añadidos para mayor claridad. Utiliza algunos mecanismos que implican continuaciones, pero estoy demasiado cansado para pensarlo más.

LegionMammal978
fuente
#[[1]]que #&@@#debe guardar un byte. !#~FreeQ~1en lugar de #~MemberQ~1guardar un byte también.
JungHwan Min
4

Mathematica, 115 109 108 104 98 bytes

(i=#~IntegerDigits~2;f:=Switch[If[i=={},0,i={##2};#]&@@i,0,0,1,f~1~f];NestWhileList[f&,f,i!={}&])&

Genera mensajes de error que pueden ignorarse de forma segura. Produce un bosque binario. Es ligeramente diferente de la salida de muestra porque 1es un Head, no el primer elemento de una lista. (por ejemplo, en 1[0, 0]lugar de {1, 0, 0})

Versión sin errores (104 bytes)

(i=#~IntegerDigits~2;f:=Switch[If[i=={},i={0}];(i={##2};#)&@@i,0,0,1,f~1~f];NestWhileList[f&,f,i!={}&])&

Explicación

i=#~IntegerDigits~2;

Convierta la entrada a una lista de base 2. Almacenarlo en i.

f:=

SetDelay flo siguiente (evaluado cada vez que fse llama):

Switch[If[i=={},0,i={##2};#]&@@i,0,0,1,f~1~f]

Switch declaración.

Primero, si iestá vacío, salida 0. De lo contrario, muestre el primer elemento iy suéltelo de la lista. Use la salida como la variable de control.

Si la variable de control es 0, salida 0. Si es así 1, salida 1[f, f](recursiva).

NestWhileList[f&,f,i!={}&]

Mientras ino esté vacío, sigue llamando f. Salida del resultado, envuelto con List.

Ejemplo

(i=#~IntegerDigits~2;f:=Switch[If[i=={},0,i={##2};#]&@@i,0,0,1,f~1~f];NestWhileList[f&,f,i!={}&])&[1337]

{1[0, 1[0, 0]], 1[1[1[0, 0], 1[0, 0]], 0]}

Solución alternativa (120 bytes)

Idéntico a mi solución de 104 bytes, pero convierte la salida al formato dado en la pregunta.

(i=#~IntegerDigits~2;f:=Switch[If[i=={},i={0}];(i={##2};#)&@@i,0,0,1,f~1~f];NestWhileList[f&,f,i!={}&]//.1[a__]:>{1,a})&
JungHwan Min
fuente
2

Python 2, 133 118 117 bytes

Parcialmente recursivo, parcialmente iterativo. Intenté usar un número entero, pero el árbol comienza con los bits más significativos, por lo que no creo que valga la pena.

def t():global b;a=b[:1];b=b[1:];return a and'0'<a and[1,t(),t()]or 0
b=bin(input())[2:]
L=[]
while b:L+=t(),
print L

Pruébalo en línea

mbomb007
fuente
1

Java 8, 367 bytes

Golfizado:

class f{static String r="";static int p=0;static void g(char[]s,int k){if(p>=s.length||s[p]=='0'){r+="0";p++;return;}else{r+="{1";p++;g(s,k+1);g(s,k+1);r+="}";}if(k==0&&p<s.length)g(s,0);}public static void main(String[]a){java.util.Scanner q=new java.util.Scanner(System.in);r+="{";g(Integer.toBinaryString(q.nextInt()).toCharArray(),0);r+="}";System.out.print(r);}}

Sin golf:

class f{
    static String r="";
    static int p=0;
    static void g(char[]s,int k){
        // if there's empty space in last tree or current character is a 0
        if(p>=s.length || s[p]=='0'){
            r+="0";
            p++;
            return;
        }
        // if current character is a 1
        else{
            r+="{1";
            p++;
            // left branch
            g(s,k+1);
            // right branch
            g(s,k+1);
            r+="}";
        }
        // if they're still trees that can be added
        if(k==0 && p<s.length)g(s,0);
    }
    public static void main(String[]a){
        java.util.Scanner q=new java.util.Scanner(System.in);
        r+="{";
        g(Integer.toBinaryString(q.nextInt()).toCharArray(),0);
        r+="}";
        System.out.print(r);
    }
}
Bobas_Pett
fuente
1

DUP , 84 bytes (82 caracteres)

0[`48-$1_>][\10*+]#%1b:[$1>][2/b;1+b:]#[['{,1.b;1-b:FF'},][0.b;1-b:]?]⇒F[b;0>][F]#

Por razones de golf, me deshice de las llaves exteriores y las comas porque no son necesarias para reconstruir los árboles.

Salidas de ejemplo:

0      → 0
1      → {100}
44     → {10{1{100}0}}
63     → {1{1{1{1{1{100}0}0}0}0}0}
404    → {1{100}{10{100}}}
1023   → {1{1{1{1{1{1{1{1{1{100}0}0}0}0}0}0}0}0}0}
1024   → {100}00000000
1025   → {100}0000000{100}
1026   → {100}000000{100}
1027   → {100}000000{1{100}0}
1028   → {100}00000{100}
1337   → {10{100}}{1{1{100}{100}}0}
4274937288 → {1{1{1{1{1{1{10{1{100}{1{1{100}{10{1{1{10{1{1{100}{100}}0}}0}0}}}0}}}0}0}0}0}0}0}
4294967297 → {100}00000000000000000000000000000{100}

Explicación:

0[`48-$1_>][\10*+]#           While loop to read in the characters and convert them into a
                              base-10 integer.
0                             Push 0 (temporary value)
 [`48-$0>]       #            While input character-48 (digit)>-1
          [     ]
           \                      Swap top values
            10                    Push 10
              *                   Multiply (temporary value by 10)
               +                  Add to input value
%                                 Pop stack (EOL)
1b:                           Variable b=1 (bit count)
[$1>][2/b;1+b:]#              While loop to convert the number to base-2 digits on the
                              data stack, MSB on top. Each iteration increments bit count b.
[$1>]          #              While (DUP>1)
     [        ]#
      2                           Push 2
       /                          MOD/DIV (pushes both mod and div on the stack)
        b;1+b:                    Fetch b, increment, store b


[['{,1.b;1-b:FF'},][0.b;1-b:]?]⇒F     
[                             ]⇒F     Define operator F:
                                      pop top stack value
 [                ]          ?        if value != 0:
  '{,1.                                   print '{1'
       b;1-b:                             fetch b, decrement b, store b
             F                            execute operator F
              F                           execute operator F again
               '},                        print '}'
                   [        ]?        if value == 0:
                    0.                    print '0'
                      b;1-b:              fetch b, decrement b, store b
[b;0>][F]#
[b;0>]   #                            While (fetch b, b>0==true)
      [F]#                                execute operator F

Pruébelo con el intérprete DUP Javascript en línea en quirkster.com o clone mi repositorio GitHub de mi intérprete DUP escrito en Julia.

ML
fuente