Crie uma parede binária


33

Dada uma matriz de números inteiros positivos na base 10, onde n > 0, emitem sua representação de uma parede binária.

Como é que isso funciona?

  1. Converta cada número em sua representação binária.
  2. Coloque a representação com zeros à esquerda no comprimento do maior, ou seja, 1, 2-> 1, 10-> 01, 10.
  3. Crie uma parede onde os 1s são tijolos 0es faltam tijolos.

Uma parede é um bloco de caracteres em que qualquer caractere imprimível representa um tijolo e um espaço ( 32) representa um tijolo ausente. Você pode escolher qualquer caractere para o tijolo; ele não precisa ser distinto do outro lado da parede, desde que não seja um caractere de espaço em branco. O caractere de tijolo ausente deve ser um espaço. Para o exemplo abaixo, eu usei *os tijolos.

Exemplo

Entrada:

[ 15, 7, 13, 11 ]
  1. [ 1111, 111, 1101, 1011 ]
  2. [ 1111, 0111, 1101, 1011 ]
  3. Saída:

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

Regras

  • As entradas devem ser obtidas na base 10, se o seu idioma aceitar outras bases, você não poderá usá-las.
  • Novas linhas à frente e à direita são permitidas.
  • A entrada pode ser considerada como uma lista de números inteiros, argumentos separados ou qualquer formato razoável.
  • A saída pode estar em qualquer formato razoável: nova string separada por linha, conjunto de linhas, conjunto 2d etc.
  • As brechas padrão não são permitidas.

Casos de teste

Observe que, no primeiro caso de teste, todas as camadas têm um tijolo vazio no final.

[ 14, 4, 6, 2 ]

*** 
 *  
 ** 
  * 

[ 1, 2, 4, 8, 16 ]

    *
   * 
  *  
 *   
*

[ 15, 11, 15, 15 ]

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

[ 11, 10, 9, 8 ]

* **
* * 
*  *
*   

Este é o código de golfe, então o código mais curto vence!


A saída pode ser uma matriz de linhas ou uma matriz 2D de caracteres?
— ovs 24/07

@ovs Desculpe, pensei em especificar que sim, você pode gerar uma matriz ou uma matriz 2D, etc. Qualquer formato razoável.
— TheLethalCoder

No caso de uma matriz 2D, podemos usar números para os tijolos em vez de caracteres? por exemplo[[1, " ", 1, " "], ...]
— Arnauld

@ Arnauld Sim, isso parece bom.
— TheLethalCoder

1
@ Giuseppe Apenas novas linhas, caso contrário, será confundido com tijolos vazios.
— TheLethalCoder

Respostas:


13

MATL , 5 bytes

B42*c

Experimente online!

Explicação

B     % Implicitly input an array of numbers. Convert to binary. 
      % Gives a matrix with each row corresponding to a number
42    % Push 42 (ASCII code of '*')
*     % Multiply
c     % Convert to char. Char 0 is displayed as space. Implicitly display

Você pode escolher qualquer caractere para o tijolo; ele não precisa ser distinto do outro lado da parede, desde que não seja um caractere de espaço em branco. sim isso significa que você provavelmente não precisa 42*ou algo assim ...
— Erik o Outgolfer

@EriktheOutgolfer Eu poderia escolher qualquer outro número, mas eu preciso desses três bytes, eu acho.
— Luis Mendo

E se houver um byte embutido para 100ou algum outro número?
— Erik the Outgolfer

11

J , 8 bytes

' *'{~#:

Experimente online!

Explicação

' *'{~#:  Input: array of integers
      #:  Convert each to binary with left-padding
' *'{~    Use the digits to index into the string ' *'

Ah, #:é por isso que isso bate Jelly.
— Erik the Outgolfer


8

Oitava, 22 bytes

@(x)[dec2bin(x)-16,'']

Experimente online

Explicação:

Economizei alguns bytes graças a Luis Mendo! Além disso, eu não percebi que poderia escolher com qual personagem construir o muro, não apenas *.

@(x)                    % Take the input as a column vector
    dec2bin(x)          % Convert each row of the input to a string with 1 and 0
                        % It gets automatically padded with zeros, to fit the longest number
    dec2bin(x)-16       % Subtract 16, to get from the ASCII-values of 1/0 (48/49)
                        % to 32/33 (space and !)
@(x)[dec2bin(x)-16,'']  % Concatenate with the empty string to convert it to a string.

Ou com de2bi:

Explicação:

@(x)                          % Take the input as a column vector
               de2bi(x)       % Convert each row of the input to a binary number.
                              % Gets automatically padded to fit the longest number
            42*de2bi(x)       % Multiply the matrix by 42, which is the ASCII-value for *
           [42*de2bi(x),'']   % Concatenate the matrix with the empty string to convert
                              % it to a string. 0 are automatically displayed as spaces
@(x)fliplr([42*de2bi(x),''])

O seguinte funciona no TIO, para mais 7 bytes:

@(x)fliplr([42*(dec2bin(x)>48),''])

Experimente aqui


5

Python 3 , 88 84 71 74 72 bytes

Um lambda que retorna uma lista de Strings, representando cada linha.

lambda n:[bin(x)[2:].replace(*'0 ').rjust(len(bin(max(n)))-2)for x in n]

Experimente online! (link para a versão separada da nova linha)

Explicação

  • lambda n:- Cria um lambda (anônimo), com um parâmetro n. Retorna implicitamente.

  • [...] - Cria uma compreensão da lista.

  • bin(x)[2:] - Obtém as representações binárias dos números.

  • .replace(*'0 ')- Substitui todas as ocorrências de 0por um espaço.

  • .rjust(len(bin(max(n)))-2) - Ajusta as representações binárias ao comprimento da mais longa.

  • for x in n- itera n, com a variável x.


Changelog

  • - 1 - 3 bytes graças a @Rod, -(...)+2= 2-(...), uso derjust()

  • Em bin()vez disso, foi adicionada uma versão inválida, pois não funcionava para 1e 2.

  • Corrigido o erro acima usando format().

  • Tipo de retorno alterado para a lista de Strings, porque foi permitido pelo OP.

  • Corrigido outro erro usando rjust()e retornando para bin(), detectado e corrigido pelo @Rod.


5

JavaScript (ES6), 81 79 bytes

Economizou 2 bytes usando números em vez de caracteres para os tijolos, conforme sugerido por Rick Hitchcock

Retorna uma matriz 2D com 1 para os tijolos.

f=(a,b=[],x=1)=>a.every(n=>n<x)?a.map(n=>b.map(i=>n&i?1:' ')):f(a,[x,...b],x*2)

Casos de teste




4

Ruby, 63 59 bytes

-4 bytes com a ajuda de Alexis Andersen

->*n{puts n.map{|i|("%#{('%b'%n.max).size}b"%i).tr'0',' '}}

Experimente online!


1
você não precisa do 0 no formato de sequência. você poderia raspar um byte, substituindo n.max.to_s(2).sizecom ('%b'%n.max).sizee você realmente não precisa para substituir o 1com*
— Alexis Andersen

@AlexisAndersen thanks :)
— daniero

4

R , 87 88 bytes

Blocos de parede representados por um 8 , porque, bem, muitos oitos.

write(ifelse((I=sapply(scan(),intToBits))[(M=max(which(I>0,T)[,1])):1,],8,' '),1,M,,'')

Experimente online!

A lista de números inteiros de entrada é convertida em uma matriz de bits que é cortada de 0 bits à direita e revertida.

A matriz reduzida é então emitida usando write uma largura de coluna que foi determinada quando a matriz foi cortada.

ifelse() é a única opção SE que funciona em vetores, infelizmente.


O @Vlo apontou que você pode usar 1em vez ""do arquivo de saída write.
— Giuseppe

@ Giuseppe obrigado pela dica #
— MickyT


3

APL (Dyalog) , 30 22 20 14 bytes

Guardado 6 bytes graças a @ Adám

' *'[⍉2⊥⍣¯1⊢⎕]

Experimente online!

(assume ⎕IO←0como padrão em muitas máquinas)

Isso recebe a entrada como uma matriz e retorna uma matriz com *s e s.

Explicação

2⊥⍣¯1⊢⎕       Convert input to binary (returns a transposed matrix of 1s and 0s)
⍉              Transpose
' *'[ ... ]    Index into this string

Salve 6 bytes com' *'[⍉2⊥⍣¯1⊢⎕]
— Adám

@ Adám Obrigado pelas dicas, eu não sabia que poderia remover o ¨.
— Kritixi Lithos

3

T-SQL, 290 bytes

declare @ int;select @=max(log(a,2))+1from @i;with t as(select convert(varchar(max),a%2)b,a/2c,@-1m,ROW_NUMBER()over(order by(select 1))r from @i union all select convert(varchar(max),concat(c%2,b))b,c/2c,m-1,r from t where m>0)select replace(b,0,' ')from t where m=0group by r,b order by r

Usa 1para a peça de tijolo, assume que a entrada vem da tabela@

Ungolfed, com alguma explicação

-- assume input is presented in an input table
declare @input table (a int)
insert into @input values (15), (7), (13), (11)

---- start here

-- figure out how many characters are needed, by taking log2
declare @max int
select @max = max(log(a, 2)) + 1
from @input

-- recursive cte
-- will join against itself, recursively finding each digit in the binary string
;with cte as
(
    select 
        convert(varchar(max), a % 2) as b, -- is the least significant bit 1 or 0
        a / 2 as c, -- remove least significant bit, for the next run
        @max - 1 as max, -- keep track of iterations left
        ROW_NUMBER() over (order by (select 1)) as rn -- keep the order of the input
    from @input

    union all -- recursive loop
              -- below columns follow the same pattern

    select convert(varchar(max), 
        concat(cte.c % 2, cte.b)) as b, -- prepend the current binary string with the newest least significant bit
        cte.c / 2 as c, 
        cte.max - 1, 
        cte.rn
    from cte
    where cte.max > 0
)
select replace(b, 0, ' ') -- swap 0s for space
from cte
where max = 0 -- only take the last iteration
group by rn, b -- grab each unique input, 
               -- need to group by row number so it can be ordered by
               -- need to group by binary string, so it can be selected
order by rn -- sort by the order the input arrived in

3

Mathematica, 40 bytes

Grid@PadLeft@IntegerDigits[#,2]/. 0->""&

Tijolos são 1s

Mathematica, 48 bytes

Grid@PadLeft@IntegerDigits[#,2]/.{0->"",1->"#"}& 

Tijolos são #


Você só precisa de uma barra no //.. ( /.Significa "substituir uma vez", //.significa "continuar fazendo a substituição até que a coisa pára de mudar".)
— Nem uma árvore

ok-fixo-obrigado
— J42161217

Você não precisa do espaço após a vírgula na função IntegerDigits.
— Mark S.

Sim, eu sei, isso acontece quando você copia / cola do notebook.fixed #
— J42161217

2

C # (.NET Core) , 112 + 18 = 130 86 + 41 = 127 bytes

a=>a.Select(n=>C.ToString(n,2).Replace("0"," ").PadLeft(C.ToString(a.Max(),2).Length))

Experimente online!

A contagem de bytes inclui 41 bytes de using System.Linq;using C=System.Convert;. Usa 1como personagem para a parede. No entanto, isso é muito longo, mesmo para C # ...


Coloque namespace System.Linq{}para salvar alguns bytes. A a.Max()garantia é verdadeira (tenho certeza de que não sou a mais inteligente com binário: P)? Iria class Convert{}salvar qualquer bytes?
— TheLethalCoder

1
Se eu colocar o programa em um determinado espaço para nome, não devo enviar o programa inteiro em vez de apenas uma lambda? Eu não tenho certeza sobre as regras para que ...
— Charlie

Eu geralmente apenas coloquei no namespace com o lambda. Acho que nunca houve uma pergunta sobre isso e está na página de dicas de C #.
— TheLethalCoder

Eu não acho que isso seja válido, pois você não pode compilá-lo sem usar importações estáticas.
— MetaColon

2
@MetaColon é a razão pela qual adicionei os bytes using System.Linq;using C=System.Convert;à contagem de bytes, pois essas duas usingdiretivas são necessárias para a compilação do código.
— 24417 Charlie

2

Retina , 63 bytes

.+
$*#<
+`(#+)\1
$1 
 #
#
{T`<`_`^(<.+(¶|$))+$
m`^<
 <
(.)<
<$1

Experimente online! Explicação:

.+
$*#<

Converta em unário e sufixo a <.

+`(#+)\1
$1 
 #
#

Converta em binário.

{T`<`_`^(<.+(¶|$))+$

Quando todos os <s tiverem chegado à esquerda, exclua todos.

m`^<
 <

Insira um espaço antes de qualquer <s que já tenha atingido a esquerda.

(.)<
<$1

Mova todos os <passos para a esquerda. Enxague e repita.


2

PowerShell , 100 bytes

$args|%{if(($c=($a=[convert]::ToString($_,2)).length)-gt$l){$l=$c}$a-replace0,' '}|%{$_.padleft($l)}

Experimente online!

Ugh, o convertbinário no PowerShell é tão doloroso. Além disso, .lengthy chama -replaceos 0espaços com, além de uma .padLeft()chamada longa para torná-los iguais..length , tudo isso resulta em um envio longo.

Sugestões de golfe para ficar abaixo de 100 são bem-vindas.


2

PHP, 84 bytes

while(++$i<$argc)echo strtr(sprintf("\n%".-~log(max($argv),2).b,$argv[$i]),10,"* ");

Felizmente, a operação de bit lança o logresultado para int. o float não funcionaria aqui.

Experimente online .


2

Clojure, 185 bytes

(fn[i](let[b(map #(Long/toBinaryString %)i)](map #(clojure.string/replace(clojure.string/replace(format(str"%0"(reduce(fn[l i](max l(count i)))0 b)"d")(read-string %))"1""#")"0"" ")b)))

Versão não destruída:

(fn [i]
    (let [b (map #(Long/toBinaryString %) i)]
        (map
            #(clojure.string/replace
                (clojure.string/replace
                    (format
                        (str "%0"
                            (reduce
                                (fn [l i] (max l(count i))) 0 b)
                            "d")
                        (read-string %))
                        "1"
                        "#")
                "0"
                " ")
        b)))

Função anônima que aceita o argumento como uma lista. Retorna as linhas como lista.

Lendo as outras respostas, aposto que poderia ser menor. clojure.string/replaceleva uma quantidade obscena de caracteres para escrever ..


2

Japonês , 33 30 bytes

¡'0p(¡X¤lÃn o)-X¤l)+X¤)£" *"gX

Experimente online!

Guardado 3 bytes graças a @Justin Mariner

Explicação

¡                              // map input integers
    (¡X¤lÃn o)                 // longest binary string length
              -X¤l)            // minus current binary string length
 '0p                           // repeat zero
                   +X¤)        // concat with current binary string
                       £       // map chars of binary string
                        " *"gX // swap 0 and 1 with ' ' and '*'

Você pode soltar os três últimos caracteres para retornar apenas uma matriz de seqüências de caracteres e usar o -Rsinalizador (não adicionado à contagem de bytes) para ver a saída associada à nova linha: aqui .
— 23717 Justin Mariner

2

Python 3 , 92 90 bytes

lambda a:[' '*(len(bin(max(a)))-len(i)-2)+i for i in[bin(i)[2:].replace(*'0 ')for i in a]]

Experimente online!

Retorna uma lista de linhas. Empilhá-los mostra que eles realmente se alinham corretamente.

['111 ', ' 1  ', ' 11 ', '  1 ']
>>>
 111 
  1  
  11 
   1 

O colapso

Converte essencialmente a matriz em binário e substitui todos os 0 por espaços. Nnúmero de espaços são adicionados à frente de cada linha em que N = [length of longest line] - [length of line].

-1 bytes Graças ao Sr. Xoder

Experimente online!


Você não pode ter espaços iniciais ou finais na saída.
— TheLethalCoder

@TheLethalCoder Oh, deve ter interpretado mal as regras! Obrigado por capturar isso.
— Graviton

90 bytes , substitua '0',' 'por *'0 '.
— Sr. Xcoder

@ Mr.Xcoder Ah interessante, nunca teria pensado nisso. Obrigado!
— Graviton

2

Japonês , 11 bytes

m¤z3 z ·r0S

Experimente online!

Explicação

m¤z3 z ·r0S  Implicit input of array
m¤           Map the array to binary strings
  z3 z       Rotate right 270° and then right 90°. This adds left padding to each string
       ·r0S  Join with newlines and replace 0s with spaces

Boa exploração com z3 z. Não sei por y yque não funciona lá, analisarei mais tarde ...
— ETHproductions

2

Java 7, 130 108 88 bytes

Salve 22 graças a @TheLethalCoder Salve 20 graças a @Xanderhall

void a(int[]b){for(int i:b)System.out.println(Long.toBinaryString(i).replace('0',' '));}

Ungolfed:

void a(int[]b){
    for(int i:b)
        System.out.println(Long.toBinaryString(i).replace('0', ' '));       
}

1
Poste incremento iem b[i]para salvar um byte. Você pode manter a saída com 1, para que não seja necessário .replace('1','*'). Use o Java 8 e compile em um lambda para salvar bytes. Se você não quiser fazer isso, int[]beconomiza um byte.
— TheLethalCoder

Obrigado! Você poderia explicar o que "Pós-incremento i em b [i] para salvar um byte." significa?
— Java Gonzar

i++avalia e idepois o incrementa (enquanto ++ifaz o oposto) para que você possa mover o i++fora do forloop e usá-lo b[i++]. Ah, e enquanto estamos nisso, você só tem uma linha dentro do seu loop para que os aparelhos não sejam necessários.
— TheLethalCoder

Verdade! Incrível, obrigado
— Java Gonzar

2
Você pode salvar alguns bytes alternando seu loop para um loop foreach. for(int x:i)Além disso, você pode usar em Long.toBinaryStringvez da versão Inteira para salvar 3 bytes.
— Xanderhall

1

Python 2, 217 bytes

Após 2 horas de codificação, decidi que esse numpy é uma má ideia para isso

import numpy as n
i=n.loadtxt("i")
o=[n.copy(i)]
o[0].fill(10)
while n.count_nonzero(i)>0:
 o.append(i%2+32)
 i=n.vectorize(lambda x:x//2)(i)
print n.fliplr(n.array(o).T).astype('uint8').view('c').tostring().decode()

Uso no Ubuntu

Instalar numpy

python2 -m pip install numpy

Crie um arquivo nomeado icom entrada no formato14 4 6 2

Corre

python2 prog.py

1

8o , 232 254 250 bytes

Código

0 >r a:new swap ( nip 2 base drop >s decimal s:len r> n:max >r a:push ) a:each drop a:new swap ( nip '0 G:c# r@ G:#> s:fmt a:push ) a:each drop rdrop a:new swap ( nip /0/ " " s:replace! a:push ) a:each drop ( nip /1/ "*" s:replace! . cr ) a:each drop

Versão ungolfed com comentários

\ convert to binary and save longest string length
: f 0 >r a:new swap ( nip 2 base drop >s decimal s:len r> n:max >r a:push ) a:each drop ;

\ pad binary number with zero
: f1 a:new swap ( nip '0 G:c# r@ G:#> s:fmt a:push ) a:each drop rdrop ;

\ replace every 0 with space
: f2 a:new swap ( nip /0/ " " s:replace! a:push ) a:each drop ;

\ replace every 1 with * and print each line of bricks
: f3 ( nip /1/ "*" s:replace! . cr ) a:each drop ;

Essas palavras devem ser invocadas em sequência (veja o exemplo)

Uso e exemplos

ok> [15,7,13,11] 0 >r a:new swap ( nip 2 base drop >s decimal s:len r> n:max >r a:push ) a:each drop a:new swap ( nip '0 G:c# r@ G:#> s:fmt a:push ) a:each drop rdrop a:new swap ( nip /0/ " " s:replace! a:push ) a:each drop ( nip /1/ "*" s:replace! . cr ) a:each drop
****
 ***
** *
* **

Ou mais claramente

ok> [15,11,15,15] f f1 f2 f3
****
* **
****
****


1

Excel VBA, 170 161 bytes

Golfe

Função de janela imediata VBE anônima que leva a entrada de formato 1 2 3 .. ndo intervalo [A1]e gera a parede binária correspondente para a janela Imediata do VBE através do intervalo[B1,C1,2:2]

n=Split([A1]):[A2].Resize(1,UBound(n)+1)=n:[C1]="=Int(1+Log(B1,2))":For Each i In n:[B1]=i:?Replace(Replace([Right(Rept(0,C1)&Dec2Bin(B1),C1)],1,"*"),0," "):Next

Formatado:

n=Split([A1])
[A2].Resize(1,UBound(n)+1)=n
[C1]="=Int(1+Log(B1,2))"
For Each i In n
[B1]=i
?Replace(Replace([Right(Rept(0,C1)&Dec2Bin(B1),C1)],1,"*"),0," ")
Next

Ungolfed

SubRotina completa que recebe a entrada do formato Array(1, 2, 3...)e envia a parede binária correspondente à janela do VBE Immediate via range[A1,B1,2:2]

Sub a(ByRef n As Variant)
    Let Range("A1").Resize(1,UBound(n)+1) = n
    Let Range("C1").Value = "=Int(1+Log(A1,2))"
    Dim i As Integer
    For Each i In n
        Let Range("A1").Value = i
        Debug.Print Replace(
                            Replace(
                                    [Right( Rept( 0, C1) & Dec2Bin( B1), C1)],
                                    1,
                                    "*"
                            ),
                            0,
                            " "
                    )
    Next
End Sub

1

Carvão , 20 bytes

WS«⸿≔IιιWι«←§ *ι≧÷²ι

Experimente online! Link é a versão detalhada do código. Funciona convertendo manualmente cada número de entrada em binário, mas imprimindo-o na ordem da direita para a esquerda. Pego a entrada como uma string terminada em nova linha, pois o Charcoal não tem uma boa maneira de inserir listas, caso contrário, escreveria algo assim, que atualmente ocupa atualmente 21 bytes:

WS⊞υIιW⌈υ«Eυ﹪κ²↓⸿≧÷²υ

Experimente online!Link é a versão detalhada do código. Esta versão vetoriza sobre a matriz de entrada, embora sua saída seja codificada para -s, o que salva um byte.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.