Saída de um caminho binário de um número

22

Para um número inteiro nsatisfatório n > 0, escreva seu valor como um caminho descendente à direita com base em sua representação binária.

Regras

  • O primeiro bit de conjunto (mais significativo) está sempre no canto superior esquerdo.
  • Quando o próximo bit estiver definido (a 1), desenhe um caractere ("preenchido") na próxima linha da mesma coluna que o caractere anterior desenhado. Tente usar espaços ("vazios") para preencher, mas qualquer caractere funcionará desde que seja sempre o mesmo.
  • Quando o próximo bit estiver desmarcado (a 0), desenhe um caractere ("preenchido") na mesma linha imediatamente à direita do caractere anterior desenhado.
  • Seu código deve suportar números com pelo menos 20 bits significativos.
  • Escreva um programa completo, uma função, um lambda, etc., mas nenhum trecho.
  • Não são permitidos espaços à esquerda (ou caracteres "vazios") / linhas
  • Qualquer número de espaços à direita (ou caracteres "vazios") / linhas permitidos
  • Qualquer tipo de entrada 1D é aceita: número, string, conjunto de booleanos, etc. Entretanto, mantenha a ordem dos bits intocados.
  • Qualquer tipo de saída 2D visual é aceita: no stdout, uma string (com dois valores distintos representando "preenchido" e "vazio"), você pode até gerar uma matriz, se desejar. Parece difícil conciliar uma lista de números com a regra "sem espaços de cabeçalho", mas estou aberto a ela se você encontrar uma maneira de usá-la. Nota: se você optar por imprimir ou retornar uma sequência, os caracteres usados ​​deverão ser caracteres ASCII no intervalo de pontos de código [32-126].
  • As brechas padrão são proibidas.
  • Este é um codegolf, então o código mais curto vence.

Exemplos

Entrada: 1

*

Entrada: 2

**

Entrada: 3

*
*

Entrada: 4

***

Entrada: 5

**
 *

Entrada: 6

*
**

Entrada: 7

*
*
*

Entrada: 25

*
***
  *

Entrada: 699050

**
 **
  **
   **
    **
     **
      **
       **
        **
         **

Entrada: 1047552

*
*
*
*
*
*
*
*
*
***********

Entrada: 525311

**********
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
Olivier Grégoire
fonte
Sandbox
Olivier Grégoire
Será que "matriz de entrada permitido de booleans" significa que tomando a entrada na forma de representação binária do número como uma matriz é permitido?
Nit
3
@Nit Qualquer tipo de entrada 1D. Portanto, se o número for 5, você pode ter uma matriz de entrada semelhante a [1,0,1]sim.
Olivier Grégoire
Então, quão livre é esse formato? Gostaria de pegar um número à medida que os dígitos binários com o primeiro 1 foram movidos para o final, então, como 9é que 1001eu gostaria que minha entrada fosse 0011. Tudo bem?
Ton Hospel
Ter o primeiro pedaço sendo o 1primeiro é parte do desafio, e (re) movê-lo seria banalizar o desafio, por isso tenho medo de dizer que não, @TonHospel. Você pode removê-lo da sua entrada no programa.
Olivier Grégoire

Respostas:

7

Gelatina , 8 bytes

¬œṗ+\Ṭz0

Um link monádico que aceita um número como uma lista de zeros e zeros (por exemplo, 13é [1,1,0,1]) retornando uma lista de listas de zeros e zeros em que a primeira lista é a primeira linha.

Experimente online! ou veja uma suíte de testes formatada

Quão?

¬œṗ+\Ṭz0 - Link: list L           e.g. [1,1,0,0,1,1,0,1] (i.e. 205)
¬        - logical NOT L               [0,0,1,1,0,0,1,0]
    \    - cumulative reduce L by:
   +     -   addition                  [1,2,2,2,3,4,4,5]
 œṗ      - partition @ truthy indices  [[1,2],[2],[2,3,4],[4,5]]
     Ṭ   - un-truth (vectorises)       [[1,1],[0,1],[0,1,1,1],[0,0,0,1,1]]
      z0 - transpose with filler 0     [[1,0,0,0],[1,1,1,0],[0,0,1,0],[0,0,1,1],[0,0,0,1]]
         -                        i.e.  1000
                                        1110
                                        0010
                                        0011
                                        0001
Jonathan Allan
fonte
11

MATL , 14 bytes

J_iB^YsJ+'o-'&XG

Produz saída gráfica como um caminho que começa nas coordenadas (0,0). Experimente no MATL Online! Ou veja alguns exemplos offline abaixo:

  • Entrada 7:

    insira a descrição da imagem aqui

    Saída:

    insira a descrição da imagem aqui

  • Entrada 699050:

    insira a descrição da imagem aqui

    Saída:

    insira a descrição da imagem aqui

Se preferir, você pode ver o caminho como coordenadas complexas para 9 bytes :

J_iB^YsJ+

Experimente online!

Explicação

J_      % Push -1j (minus imaginary unit)
i       % Push input number
B       % Convert to binary. Gives an array of 0 and 1 digits
^       % Power, element-wise. A 0 digit gives 1, a 1 digit gives -1j
Ys      % Cumulative sum. Produces the path in the complex plane
J+      % Add 1j, element-wise. This makes the complex path start at 0
'o-'    % Push this string, which defines plot makers
&XG     % Plot
Luis Mendo
fonte
7

MATL , 10 bytes

YsG~YsQ1Z?

Insere uma matriz de dígitos binários. Produz uma matriz.

Experimente online!

Explicação

Ys    % Implicit input: array of binary digits. Cumulative sum. This gives the
      % row coordinates
G     % Push input again
~     % Negate: change 0 to 1 and 1 to 0
Ys    % Cumulative sum
Q     % Add 1. This gives the column coordinates
1Z?   % Matrix containing 1 at those row and column coordinates and 0 otherwise.
      % Implicit display
Luis Mendo
fonte
6

Python 2 , 100 99 81 78 73 66 bytes

a='';x=0
for c in input():a+=('\n'+' '*x)*c+'*';x+=1-c
print a[1:]

Experimente online!

Versão recursiva:

Python 2 , 71 69 67 bytes

f=lambda n,x=0:n and('\n'[:x]+' '*x)*n[0]+'*'+f(n[1:],x+1-n[0])or''

Experimente online!

TFeld
fonte
6

Carvão , 22 20 19 11 10 bytes

F⮌S¿Iι↑*←*

Apenas minha segunda resposta de carvão vegetal até agora.

Toma a entrada como String binária (ou seja, 699050como 10101010101010101010).

-9 bytes graças a @ Neil sugerindo um loop para trás.

Experimente online.

Explicação:

Leia STDIN como string na ordem inversa:

Reverse(InputString())
⮌S

Faça um loop sobre seus dígitos binários como strings ι:

For(Reverse(InputString()))
F⮌S

Se ιconvertido para um número for 1, imprima *para cima, ou imprima *para a esquerda.

If(Cast(i)) Print(:Up,"*"); Else Print(:Left,"*");
¿Iι↑*←*
Kevin Cruijssen
fonte
1
Isso seria a metade do tempo se você imprimisse a corda no sentido inverso, começando no final e trabalhando para cima e para a esquerda.
611 Neil
@ Neil Ok, agora deve ser corrigido. Obrigado! -8 bytes
Kevin Cruijssen 06/04
1
Salve outro byte removendo os {}s.
619 Neil
1
Basecusta apenas 1 byte como você não precisa o Castem tudo: F⮌↨N²¿ι↑*←*.
619 Neil
1
@KevinCruijssen Desculpe pela resposta tardia, mas para responder às suas perguntas: não há reversão -v, já que o Charcoal foi projetado como uma linguagem de golfe e eu adicionei o modo detalhado apenas para facilitar a digitação e compreensão. (Eu posso adicionar um, se você quiser). -aé uma abreviação de --ast, eu o adicionei (formato retirado do PyTek btw) para me ajudar a entender o código sucinto com o mínimo de esforço possível: P (e realmente ajuda quando você acidentalmente estraga a ordem dos argumentos). Além disso, não -lé uma opção separada . (também faça isso -hpara obter ajuda com / descrições de argumentos da linha de comando)
ASCII-only
6

C # (.NET Core) , 155 123 120 113 101 bytes

Salva 32 bytes devido à possibilidade de entrada ser recebida como uma matriz de bits.
Guardado 7 bytes graças a @auhmaan.
Guardou 10 bytes graças a @KevinCruijssen.

n=>{var m="";for(int i=0,c=1;i<n.Length;)m+=n[i++]<1?c++%1+"":(i>1?"\n":"")+"0".PadLeft(c);return m;}

Experimente online!

Ian H.
fonte
Você não pode alterar +new string(' ',c)+"*"para +"*".PadLeft(c)(salva 7 bytes)?
Auhmaan 6/04
@auhmaan Você está certo, obrigado!
Ian H.
-4 bytes por impressão 0em vez de *: if(n[i++]<1){m+="*";c++;}a if(n[i++]<1)m+=c++%1;e "*".PadLeft(c);para"0".PadLeft(c);
Kevin Cruijssen
Correção, é realmente -12 bytes, porque m+=agora pode ser um ternário-se:m+=n[i++]<1?c++%1+"":(i>1?"\n":"")+"0".PadLeft(c);
Kevin Cruijssen
1
@KevinCruijssen Obrigado, usar 0's' e o uso do operador ternário são realmente inteligentes! Eu também resolvi o caso 699060, simplesmente definindo cpara um no começo, meio que perdi isso ao verificar os casos de teste.
Ian H.
5

05AB1E , 18 17 14 bytes

γ€gć¸s>«1IÔ·ÌΛ

Experimente online!

Explicação

γ€g             # Push the input as the array as chuncks of consecutive elements, map with length
   ć¸s>«        # Increment each value except the first one
        1I      # Push 1 and the input       
          Ô     # Push connected uniquified input (first elements of each chunck of consecutive elements in the input)
           ·Ì   # Map each with 2 * a + 2
             Λ  # Draw canvas :-)
  • 3 bytes graças a @Emigna

Explicação da tela 05AB1E

Kaldo
fonte
1
γ€gć¸s>«1IÔ·ÌΛdeve salvar 4 bytes.
Emigna
@ Emigna Brilliant, obrigado! Totalmente se esqueceu de que houve uma a + 2 incorporado o:
Kaldo
3

Haskell , 65 bytes

f(a:b)|a="*":f b|(x:y)<-f b=('*':x):map(' ':)y
f[]=["*"]
f.tail

Experimente online!

Recebe entrada como uma lista de booleanos.

Caril PAKCS, 70 bytes

u(a:b)=('*':a):map(' ':)b
f(a:b)|a="*":f b|1>0=u$f b
f[]=["*"]
f .tail

A porta do Haskell responde, mas como <-não funciona no Curry, precisamos fazer uma função auxiliar u. Também precisamos adicionar um espaço entre fe. para que Curry o analise como uma composição em vez de um ponto.

Isso também funciona no MCC Curry, mas não no Sloth Curry (que é o único suportado pelo TIO).

Assistente de Trigo
fonte
3

Emojicode , 251 bytes

🐖🎅🏿🍇🍦b🔡🐕2🍦c🔤*🔤🍮e🔤🔤🍮y🔤🔤🍦k🍡b🔂i k🍇🍊😛🔡i🔤1🔤🍇🍊😛y e🍇🍉🍓🍇😀y🍉🍮y🔤🔤🍮y🍪e c🍪🍉🍓🍇🍮y🍪y c🍪🍮e🍪🔤 🔤 e🍪🍉🍉😀y🍉

Experimente online!

Definitivamente, essa não é uma solução para o golfe, mas não existe uma pessoa viva que considere o código Emoji como um idioma para o golfe. No entanto, no processo de me sujeitar aos horrores que são a sintaxe do código emoji em um esforço para me ensinar essa monstruosidade de uma língua, fiquei agradavelmente surpreendido com o quão poderoso e eficiente pode ser.

Explicação:

🐋 🚂 🍇    👴 Define Class
🐖🎅🏿🍇    👴 Define Method
🍦b🔡🐕2    👴Convert Input integer to binary string
🍦c🔤*🔤    👴 asterisk string
🍮e🔤🔤    👴 Spacing string
🍮y🔤🔤    👴 output string
🍦k🍡b    👴 translate to iteratable
🔂i k🍇    👴 for-in loop to iterate over each digit 
🍊😛🔡i🔤1🔤🍇    👴 if digit is 1:
🍊😛y e🍇🍉    👴 don't print initial newline
🍓🍇😀y🍉    👴 print spaces + asterisks
🍮y🔤🔤    👴 reset output string
🍮y🍪e c🍪🍉    👴 add correct number of spaces and one asterisk
🍓🍇    👴 if digit is 0:
🍮y🍪y c🍪    👴 add an asterisk to the output string
🍮e🍪🔤 🔤 e🍪    👴 add another space to the space string
🍉🍉
😀y    👴 print one last output string
🍉🍉
🏁🍇    👴 Start Program
 🎅🏿 699050    👴 Call Method
🍉
X1M4L
fonte
2

JavaScript (ES6), 48 bytes

O mesmo formato de E / S e a mesma lógica da versão recursiva abaixo.

a=>a.map((n,i)=>n?i&&p+0:+(p+=' '),p=`
`).join``

Experimente online!

Ou 42 bytes, se este formato for aceitável.


Versão recursiva, 56 bytes

Recebe a entrada como uma matriz de números inteiros (0 ou 1). Usa 0para preenchido e espaço para vazio.

f=([n,...a],p=`
`,x=0)=>1/n?(n?x+0:+(p+=' '))+f(a,p,p):a

Experimente online!

Comentado

f = (               // f = recursive function taking:
  [n, ...a],        //   n = current bit; a[] = remaining bits
  p = `\n`,         //   p = padding string, initialized to a linefeed
  x = 0             //   x = 0 on the 1st iteration / equal to p after that
) =>                //
  1 / n ?           // if n is defined:
    ( n ?           //   if n = 1:
        x + 0       //     append x + 0 --> either the integer 0 on the first iteration
                    //                      or the padding string followed by a '0'
      :             //   else:
        +(          //     append the integer 0 (whitespace coerced to a number)
          p += ' '  //     and append a space to the padding string
        )           //
    ) + f(a, p, p)  //   append the result of a recursive call with x = p
  :                 // else:
    a               //   append the empty array a[], forcing coercion to a string
Arnauld
fonte
2

Utilitários Bash + GNU, 38

dc -e?2op|sed 's/\B1/^K^H*/g;s/[10]/*/g'

Aqui ^Ke ^Hsão literais caracteres de tabulação vertical e controle de retrocesso. Como eles não são renderizados corretamente nos navegadores, portanto, esse script pode ser recriado da seguinte maneira:

base64 -d <<< ZGMgLWU/Mm9wfHNlZCAncy9cQjEvCwgqL2c7cy9bMTBdLyovZyc= > binpath.sh

Corra em um terminal. A entrada é via STDIN.

Essa resposta pode exagerar nas especificações - na verdade, não há caracteres iniciais em cada linha de saída - todo o posicionamento é feito com caracteres de controle. Se isso for muito exagerado, a saída poderá ser canalizada para |col -x|tac11 bytes adicionais.

Trauma Digital
fonte
2

Lote, 113 bytes

@set s=
:l
@shift
@if %1.==0. set s=%s%+&goto l
@echo %s%+
@if not %s%.==. set s=%s:+= %
@if %1.==1. goto l

Leva uma lista de bits como argumentos de linha de comando. Usa em +vez de *porque *tem um significado especial nas %s:...=...%expansões.

Neil
fonte
2

Java 10, 100 106 bytes

b->{var s="";int i=0,j;for(var c:b){if(c)for(s+="\n",j=i;j-->0;)s+=0;else++i;s+=1;}return s.substring(1);}

Pega uma matriz de booleanos e retorna uma String ( 0s estão vazios, 1s são preenchidos). Experimente online aqui .

Agradecimentos a Olivier Grégoire por me ajudar um pouco mais no golfe e por me alertar para o fato de que meu formato de saída não estava dentro das especificações.

Versão não destruída:

b -> { // lambda taking an array of booleans as argument
    var s = ""; // the output String
    int i = 0,  // the number of "empty" characters to output
    j;          // iterator variable for outputting the "empty" characters
    for(var c : b) { // iterate over the boolean array (the binary digits)
        if(c) // if it's a '1'
            for(s += "\n", // output a newline
            j = i; j-- > 0;) s += 0; // output the "empty" characters
        else // if it's a '0'
            ++i; // move one to the right on the next line
        s += 1; // output the "filled" character
    }
    return s.substring(1); // output the constructed String, minus the leading newline
}
OOBalance
fonte
Joguei 5 bytes de golfe:{if(c){s+="\n";for(j=i;j-->0;)s+=0;}else++i;s+=1;}
Olivier Grégoire
Ainda mais:{if(c)for(s+="\n",j=i;j-->0;)s+=0;else++i;s+=1;}
Olivier Grégoire
No entanto, você não imprime na primeira linha, mas na segunda. Do desafio: "Não são permitidos espaços / linhas (ou caracteres" vazios "))"
Olivier Grégoire
@ OlivierGrégoire Obrigado. Eu editei.
OOBalance
2

Java (JDK 10) , 83 bytes

a->{int m[][]=new int[20][20],r=0,i=0;for(int b:a)m[r+=i<1?0:b][i++-r]=1;return m;}

Experimente online!

  • Suporta no máximo 20 bits.
  • Entrada como int[]
  • Saída como int[][]
Olivier Grégoire
fonte
1

Haskell , 126 bytes

(#)n=maximum.map(!!n)
f l|s<-scanl1(zipWith(+))$(\a->[1-a,a])<$>l=unlines[[last$' ':['#'|elem[x,y]s]|x<-[0..0#s]]|y<-[1..1#s]]

Insira como uma lista de zeros e uns. Transforma o número em deslocamento x↦[1-x,x]e calcula as somas parciais. A saída final é feita com duas compreensões de lista aninhadas.

Experimente online!

Angs
fonte
1

R , 59 bytes

function(n,x=sum(n|1))matrix(1:x^2%in%cumsum((n-1)%%x+1),x)

Experimente online!

Recebe a entrada como uma matriz de bits.

Retorna uma matriz booleana de TRUEe FALSErepresentando ae *a , respectivamente.

Também possui algumas coisas no rodapé para imprimir uma matriz correspondente às especificações acima, para facilitar o teste.

Giuseppe
fonte
1

APL + WIN, 65 ou 46 bytes

Solicita a entrada do número inteiro

n←+/i←((1+⌊2⍟n)⍴2)⊤n←⎕⋄m←(n,n)⍴' '⋄m[⊂[2](+\i),[1.1]1++\~i]←'*'⋄m

ou para vetor numérico da representação binária do número inteiro

m←(2⍴+/n←⎕)⍴' '⋄m[⊂[2](+\i),[1.1]1++\~i]←'*'⋄m

assumindo que li os comentários para certas respostas corretamente e a última entrada é permitida.

Graham
fonte
1

Pitão, 23 bytes

p\*VtQINp+b*Zd.?=hZ)p\*

Experimente aqui

Explicação

p\*VtQINp+b*Zd.?=hZ)p\*
p\*                       Print the leading *.
   VtQ                    For each bit (excluding the leading 1)...
      IN      .?   )      ... If the bit is set...
        p+b*Zd            ... Print a newline and a bunch of spaces...
                =hZ       ... Otherwise, increase the count of spaces...
                    p\*   ... Then print the next *.

fonte
1

Perl 5 -p , 54 36 bytes

s/./$&?"
".$"x$i.1:++$i&&1/ge;s/.//s

Experimente online!

Corte-o depois que percebi que a entrada poderia ser um pouco complicada.

Xcali
fonte
1

SmileBASIC, 64 59 57 bytes

INPUT N@L
GPSET X,Y
B=N<0X=X+B
Y=Y+(X>B)N=N<<1ON!N GOTO@L

O bit mais alto (bit de sinal) é verificado e, se for 1, a posição X aumenta. Se o bit de sinal é menor que a posição X (ou seja, o bit de sinal é 0 e X não é 0), a posição Y aumenta.

O primeiro movimento sempre será horizontal, portanto o movimento Y é bloqueado até depois do primeiro movimento X. Isso garante que a posição Y não aumente durante os 0 bits iniciais.

Então N é deslocado para a esquerda e isso se repete até N atingir 0.

12Me21
fonte
1

Ruby , 63 bytes

->n{s=""
n.to_s(2).gsub(/./){$&==?1?"
"+s+?*:(s+=" ";?*)}[1,n]}

Experimente online!

Restabelecer Monica iamnotmaynard
fonte
1

Japonês , 19 17 bytes

Ë?R+Tî +QT©Qìx
Ë?                 // Map over the input and if the current value is 1:
  R+               // Return a new line and
    Tî +           // a space repeated T (with initial value 0) times and
        Q          // a \".
         :         // If the current value is 0:
          °T       // Increment T
            ©Q     // and return \".
              Ã    // When all of that is done,
               ¬   // turn the array into a string
                x  // and trim it, removing the excess new line at the start.

Recebe a entrada como uma matriz de bits, por exemplo [1,0,1], em "vez de *.
Raspou dois bytes graças a Oliver .

Experimente online!

Nit
fonte
Agradável. Você pode substituir SpTpor - îé semelhante a p, exceto pelo padrão " ". Além disso, há um atalho para q :¬
Oliver
@ Oliver Obrigado, eu não sabia î, certamente muito útil. Costumo verificar se há chances de usar os atalhos, mas ainda sinto falta de alguns deles, muito obrigado por sua ajuda.
Nit
1

Python 2, 113 bytes

def f(a):
 o='*';r=[o]
 for i in bin(a)[3:]:
  if'0'<i:r+=[' '*len(r[-1][1:])]
  r[-1]+=o
 print'\n'.join(r)

Não tenho certeza se este conta (ele gera uma matriz de cada uma das linhas), mas se sim, então alterarei minha contagem de bytes para 103:

def f(a):
 o='*';r=[o]
 for i in bin(a)[3:]:
  if'0'<i:r+=[' '*len(r[-1][1:])]
  r[-1]+=o
 print r
sonrad10
fonte
1

TI-Basic (TI-84 Plus CE), 85 bytes

Prompt L
1→X
1→Y
DelVar [A]
sum(LL
{Ans,1-Ans+dim(LL→dim([A]
1→[A](Y,X
For(I,2,dim(LL
Y+LL(I→Y
X+not(LL(I→X
1→[A](Y,X
End
[A]

Solicita uma lista booleana, retorna uma matriz de 0 e 1.

Percorre a lista, incrementando X se o próximo 'bit' for 0, alterando Y caso contrário, adicionando um 1 à matriz nesse local e retornando a matriz no final.

O TI-Basic é uma linguagem tokenizada .

  • 1 byte: Prompt , L* 6, (nova linha) * 12, 1* 5, * 7, X* 5, Y* 5, sum(, L* 5, {, Ans* 2, ,* 5, -, +* 3,dim( * 3, (* 4, For(, I* 3, 2, not(, End= 73 bytes
  • 2 bytes: Delvar , [A]* 5 = 12 bytes
  • Total: 85 bytes

TI-Basic (TI-84 Plus CE), 56 bytes

Prompt L
1→X
1→Y
Output(Y,X,"*
For(I,2,dim(LL
Y+LL(I→Y
X+not(LL(I→X
Output(Y,X,"*
End

Os mesmos processos acima, mas usando a saída gráfica (limitada pelo tamanho da tela: 10 linhas, 26 colunas, no máximo 10 1s e 25 0s) como segue, em vez de adicionar a uma matriz.

pizzapants184
fonte
1

Pitão, 30 bytes

JZFG.BQIsGIJk)p+*ZdN.?pN=hZ)=J

Experimente online!

Usos " vez de *.

Tradução Python 3:
Q=eval(input())
Z=0
J=Z
for G in "{0:b}".format(Q):
    if int(G):
        if J:
            print()
        print(Z*' '+'"',end='')
    else:
        print('"',end='')
        Z+=1
    J=Q
hakr14
fonte
1

x86 .COM, 32 bytes

00h: 66 D1 E6 66 0F BD CE BF 24 AD 8E DF 41 66 0F A3 
10h: CE 19 DB 81 E3 9E 00 8D 79 02 C6 05 2A E2 EE C3 

fun:
shl esi, 1
bsr ecx, esi
mov di, $ad24
mov ds, di
inc cx
lab2:
bt esi, ecx
sbb bx,bx
and bx,158
lea di,[di+2+bx]
mov [di],byte '*'
lab1:loop lab2
ret  
l4m2
fonte