Plante uma floresta binária!

24

Inspirado por A014486 .

Desafio

Dada uma entrada inteira na base 10, construa uma representação para a floresta binária correspondente à entrada. As representações incluem, mas não estão limitadas a, matrizes e cadeias aninhadas.

Quão?

Converta a entrada em binário. 1s representam ramos 0es representam folhas.

Para facilitar a compreensão, vamos usar 834(1101000010 em binário) como exemplo.


Começamos com o primeiro dígito. O primeiro dígito é a 1, então desenhamos ramificações:

\ /
 1 1

ou como uma matriz, {{1}}


O próximo dígito é 1, portanto, desenhamos mais ramos (vamos da esquerda para a direita):

\ /
 1 1
  \ /
    1 1

ou como uma matriz, {{1, {1}}}


O próximo dígito é 0, então colocamos uma folha:

0 0
 \ /
  1 1
   \ /
     1 1

ou como uma matriz, {{1, {1, 0}}}


O próximo dígito é a 1, então colocamos um ramo:

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

ou como uma matriz, {{1, {1, 0, {1}}}}


Repetindo o processo, obtemos a seguinte árvore após o oitavo dígito:

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

ou como uma matriz, {{1, {1, 0, {1, 0, 0}}, 0}}


Para os dígitos restantes, desenhamos mais árvores:

O nono dígito é um 0, então colocamos uma folha (aww, é um broto jovem!)

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

ou como uma matriz, {{1, {1, 0, {1, 0, 0}}, 0}, 0}


Quando usamos todos os dígitos, terminamos com o seguinte:

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

ou como uma matriz, {{1, {1, 0, {1, 0, 0}}, 0}, 0, {1, 0}}


Isso parece estranho, por isso, preenchemos um zero para completar a árvore:

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

ou como uma matriz, {{1, {1, 0, {1, 0, 0}}, 0}, 0, {1, 0, 0}}

Observe que o achatamento da matriz gera o número original em binário, mas com um zero preenchido.

Critério

  • A saída deve mostrar claramente a separação das árvores e galhos (se não for uma matriz aninhada, explique seu formato de saída).
  • A extração de todos os dígitos da saída deve ser idêntica à representação binária da entrada (com os zero preenchidos do processo acima).

Casos de teste

A saída pode diferir desde que atenda aos critérios.

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

Pontuação

Isso é , então os bytes mais baixos vencem!

JungHwan Min
fonte
5
Eu evitaria usar bônus - geralmente não melhora o desafio.
Sanchises
11
@Sanchises Adicionei o bônus para ver as respostas com a visualização ... De que outra forma eu poderia incentivar as pessoas a tentar fazer uma visualização como saída?
JungHwan Min
4
(re seu comentário) Requer?
msh210
11
@JungHwanMin Veja o que eu liguei com mais detalhes (especialmente os comentários); ou, na mesma pergunta Meta, esta resposta. Sua pergunta atual pede que os pôsteres criem 2 ^ 2 = 4 programas e calculem a pontuação de cada programa antes de enviar o melhor programa de pontuação. Exija-o quando achar que ele é um desafio melhor ou remova-o se achar que ele é um desafio pior.
Sanchises
2
@JungHwanMin Fair o suficiente. Eles devem jogar 3 programas e calcular cada pontuação individual antes de enviar uma resposta. O que você tem aqui são três desafios agrupados em um. Eu recomendaria postar a visualização como um desafio separado.
Sanchises

Respostas:

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 uma função fque retorna uma matriz aninhada. O código HTML é apenas para teste.

PurkkaKoodari
fonte
Por um segundo eu estava pensando "o que diabos está $&fazendo sem .replace?" : P
ETHproductions
@ETHproductions Eu meio que fiquei entediado e ofusquei os nomes das variáveis. Pena que o JS não permite outros símbolos de um único símbolo: 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<^

Experimente online!

Explicação

A linha 1 lê um número de stdin e a linha 2 converte esse número em uma sequência binária que ele armazena no campo de jogo na linha 10. As linhas 3 a 5 então iteram sobre esses dígitos binários, produzindo a representação de árvore apropriada à medida que cada dígito é processado. A pilha Befunge é usada para acompanhar a profundidade da árvore e quanto espaço de folha resta em cada nível, para que saibamos quando criar um novo galho. As linhas 6 e 7 lidam com o 0preenchimento final para preencher as folhas vazias.

Para jogar isso o máximo possível, removi as vírgulas da saída, bem como as chaves externas estranhas. Isso ainda não superou a solução Mathematica, mas foi divertido tentar.

Se você quiser ver como era o formato de saída detalhado original, salvei uma versão anterior do código aqui (131 bytes).

James Holderness
fonte
11
(isso não tem upvotes suficientes: D)
Addison Crump
4

Mathematica, 167 161 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]&,
{}]&

Função anônima. Pega um número como entrada e retorna uma lista arbitrariamente aninhada de números como saída. Quebras de linha adicionadas para maior clareza. Usa algum mecanismo que envolve continuações, mas estou cansado demais para pensar sobre isso por mais tempo.

LegionMammal978
fonte
#[[1]]a #&@@#deve salvar um byte. !#~FreeQ~1em vez de #~MemberQ~1salvar um byte também.
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!={}&])&

Gera mensagens de erro que podem ser ignoradas com segurança. Produz uma floresta binária. É um pouco diferente da saída de amostra porque 1é um Head, não o primeiro elemento de uma lista. (por exemplo, em 1[0, 0]vez de {1, 0, 0})

Versão sem erros (104 bytes)

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

Explicação

i=#~IntegerDigits~2;

Converta a entrada em uma lista de base 2. Guarde-o i.

f:=

SetDelay fo seguinte (avaliado sempre que ffor chamado):

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

Switch declaração.

Primeiro, se iestiver vazio, saia 0. Caso contrário, imprima o primeiro elemento de ie solte-o da lista. Use a saída como a variável de controle.

Se a variável de controle for 0, output 0. Se for 1, saída 1[f, f](recursiva).

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

Enquanto inão estiver vazio, continue ligando f. Saída do resultado, embrulhado com List.

Exemplo

(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]}

Solução alternativa (120 bytes)

Idêntico à minha solução de 104 bytes, mas converte a saída no formato fornecido na pergunta.

(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
fonte
2

Python 2, 133 118 117 bytes

Parcialmente recursivo, parcialmente iterativo. Tentei usar um número inteiro, mas a árvore começa com os bits mais significativos, então não acho que valha a 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

Experimente online

mbomb007
fonte
1

Java 8, 367 bytes

Golfe:

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

Ungolfed:

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
fonte
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 razões de golfe, me livrei das chaves externas e das vírgulas, porque elas não são necessárias para reconstruir as árvores.

Exemplo de saídas:

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}

Explicação:

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

Experimente com o interpretador Javascript DUP on-line em quirkster.com ou clone meu repositório GitHub do meu interpretador DUP escrito em Julia.

ML
fonte