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!

TheLethalCoder
fonte
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
Luis Mendo
fonte
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 ' *'
milhas
fonte
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

Stewie Griffin
fonte
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.

Mr. Xcoder
fonte
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

Arnauld
fonte
4

05AB1E , 9 bytes

bí.Bí»0ð‡

Experimente online!

Erik, o Outgolfer
fonte
Bata em mim por 38 segundos. Eu tinha b0ð:í.Bí»por 9 bytes também.
Riley
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!

daniero
fonte
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.

MickyT
fonte
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
Kritixi Lithos
fonte
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
Brian J
fonte
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 #

J42161217
fonte
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 # ...

Charlie
fonte
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.

Neil
fonte
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.

AdmBorkBork
fonte
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 .

Titus
fonte
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 ..

Joshua
fonte
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 '*'
powelles
fonte
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!

Graviton
fonte
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
Justin Mariner
fonte
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', ' '));       
}
Java Gonzar
fonte
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
Евгений Новиков
fonte
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
****
* **
****
****
Chaos Manor
fonte
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
Taylor Scott
fonte
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.

Neil
fonte