Crea un muro binario


33

Dato un array di numeri interi positivi in ​​base 10, dove n > 0, emette la loro rappresentazione di un muro binario.

Come funziona?

  1. Converti ogni numero nella sua rappresentazione binaria.
  2. Riempi la rappresentazione con zeri iniziali per la lunghezza di quella più lunga, ovvero 1, 2-> 1, 10-> 01, 10.
  3. Crea un muro in cui le 1s sono mattoni e le 0s sono mattoni mancanti.

Un muro è un blocco di caratteri in cui qualsiasi personaggio stampabile rappresenta un mattone e uno spazio ( 32) rappresenta un mattone mancante. Puoi scegliere qualsiasi personaggio per il mattone, non è necessario che sia distinto attraverso il muro purché non sia un personaggio bianco. Il carattere di mattone mancante deve essere uno spazio. Nell'esempio seguente ho usato *i mattoni.

Esempio

Ingresso:

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

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

Regole

  • L'input deve essere preso nella base 10, se la tua lingua accetta altre basi non puoi usarle.
  • Sono consentite nuove e iniziali linee.
  • L'input può essere preso come un elenco di numeri interi, argomenti separati o qualsiasi formato ragionevole.
  • L'output può essere in qualsiasi formato ragionevole: nuova stringa separata da riga, matrice di linee, matrice 2d ecc.
  • Le scappatoie standard non sono ammesse.

Casi test

Si noti che nel primo caso di test tutti gli strati hanno un mattone vuoto alla fine.

[ 14, 4, 6, 2 ]

*** 
 *  
 ** 
  * 

[ 1, 2, 4, 8, 16 ]

    *
   * 
  *  
 *   
*

[ 15, 11, 15, 15 ]

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

[ 11, 10, 9, 8 ]

* **
* * 
*  *
*   

Questo è il codice golf, quindi vince il codice più corto!


L'output può essere un array di righe o un array di caratteri 2D?
Ovs,

@ovs Mi dispiace averlo specificato, sì, è possibile produrre un array o un array 2d ecc. Qualsiasi formato ragionevole.
TheLethalCoder

Nel caso di un array 2D, possiamo usare numeri per i mattoni anziché caratteri? ad es.[[1, " ", 1, " "], ...]
Arnauld,

@Arnauld Sì, sembra perfetto.
TheLethalCoder

1
@Giuseppe Solo nuove linee, altrimenti verrà confuso per mattoni vuoti.
TheLethalCoder

Risposte:


13

MATL , 5 byte

B42*c

Provalo online!

Spiegazione

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

Puoi scegliere qualsiasi personaggio per il mattone, non è necessario che sia distinto attraverso il muro purché non sia uno spazio bianco. sì, ciò significa che probabilmente non hai bisogno 42*o qualcosa del genere ...
Erik the Outgolfer,

@EriktheOutgolfer Potrei scegliere qualsiasi altro numero, ma credo di aver bisogno di quei tre byte.
Luis Mendo,

Cosa succede se è presente un built-in a 1 byte 100o un altro numero?
Erik the Outgolfer,

11

J , 8 byte

' *'{~#:

Provalo online!

Spiegazione

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

Oh, quindi #:è per questo che batte Jelly.
Erik the Outgolfer,


8

Ottava, 22 byte

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

Provalo online

Spiegazione:

Salvataggio di alcuni byte grazie a Luis Mendo! Inoltre, non ho notato che avrei potuto scegliere con quale personaggio costruire il muro, non solo *.

@(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.

O con de2bi:

Spiegazione:

@(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),''])

Quanto segue funziona su TIO, per altri 7 byte:

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

Provalo qui


5

Python 3 , 88 84 71 74 72 byte

Un lambda che restituisce un elenco di stringhe, che rappresentano ciascuna riga.

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

Provalo online! (collegamento alla versione separata della nuova riga)

Spiegazione

  • lambda n:- Crea un lambda (anonimo), con un parametro n. Ritorna implicitamente.

  • [...] - Crea una comprensione dell'elenco.

  • bin(x)[2:] - Ottiene le rappresentazioni binarie dei numeri.

  • .replace(*'0 ')- Sostituisce tutte le occorrenze di 0con uno spazio.

  • .rjust(len(bin(max(n)))-2) - Riempie le rappresentazioni binarie per la lunghezza di quella più lunga.

  • for x in n- Scorre n, con la variabile x.


changelog

  • - 1 - 3 byte grazie a @Rod, -(...)+2= 2-(...), uso dirjust()

  • Aggiunta invece una versione con bin(), che non era valida poiché non funzionava per 1e 2.

  • Risolto il bug sopra usando format().

  • Modificato il tipo di ritorno nell'elenco delle stringhe, perché era consentito dall'OP.

  • Risolto un altro bug che utilizzava rjust()e tornava a bin(), individuato e corretto da @Rod.


5

JavaScript (ES6), 81 79 byte

Hai salvato 2 byte usando i numeri anziché i caratteri per i mattoni, come suggerito da Rick Hitchcock

Restituisce un array 2D con 1 per i mattoni.

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)

Casi test




4

Rubino, 63 59 byte

-4 byte con l'aiuto di Alexis Andersen

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

Provalo online!


1
non è necessario lo 0 nel formato stringa. potresti radere un byte sostituendolo n.max.to_s(2).sizecon ('%b'%n.max).sizee in realtà non è necessario sostituire il 1con*
Alexis Andersen,

@AlexisAndersen grazie :)
daniero,

4

R , 87 88 byte

Blocchi di muro rappresentati da un 8, perché, ben un sacco di otto.

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

Provalo online!

L'elenco intero di input viene convertito in array di bit che vengono tagliati di 0 bit finali e invertiti.

L'array ridotto viene quindi emesso usando writee una larghezza di colonna che è stata determinata al momento del taglio dell'array.

ifelse() è l'unica opzione IF che sfortunatamente funziona con i vettori.


@Vlo ha sottolineato che è possibile utilizzare 1anziché ""per il file di output in write.
Giuseppe,

@Giuseppe grazie per l'informazione
MickyT


3

APL (Dyalog) , 30 22 20 14 byte

6 byte salvati grazie a @ Adám

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

Provalo online!

(presuppone ⎕IO←0che questo sia predefinito su molte macchine)

Questo prende l'input come un array e restituisce una matrice con *s e s.

Spiegazione

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


@Adám Grazie per i suggerimenti, non sapevo di poter rimuovere ¨.
Kritixi Lithos,

3

T-SQL, 290 byte

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

usi 1 per il pezzo in mattoni, presuppone che l'input provenga dalla tabella@

Ungolfed, con qualche spiegazione

-- 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 byte

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

I mattoni sono 1s

Mathematica, 48 byte

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

I mattoni sono #


Dovresti avere solo una barra nel file //.. ( /.significa "sostituisci una volta", //.significa "continua a fare la sostituzione finché la cosa non smette di cambiare".)
Non un albero

ok-fixed-thanks
J42161217

Non è necessario lo spazio dopo la virgola nella funzione IntegerDigits.
Mark S.

sì, lo so, questo succede quando si copia / incolla da notebook
fisso

2

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

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

Provalo online!

Il conteggio dei byte include 41 byte da using System.Linq;using C=System.Convert;. Usa 1come personaggio per il muro. Tuttavia, questo è troppo lungo anche per C # ...


Inserire namespace System.Linq{}per salvare alcuni byte. È a.Max()garantito per essere vero (sono sicuro che non sono il più intelligente con binario: P)? Salverebbe class Convert{}qualche byte?
TheLethalCoder

1
Se posiziono il programma in un determinato spazio dei nomi, non dovrei inviare l'intero programma anziché solo un lambda? Non sono sicuro delle regole per questo ...
Charlie

Di solito ho appena inserito nello spazio dei nomi con lambda. Non penso che ci sia mai stata una domanda al riguardo ed è nella pagina dei suggerimenti di C #.
TheLethalCoder

Non credo sia valido, dal momento che non è possibile compilarlo senza utilizzare le importazioni statiche.
MetaColon,

2
@MetaColon è questo il motivo per cui ho aggiunto i byte using System.Linq;using C=System.Convert;al conteggio dei byte, poiché queste due usingdirettive sono necessarie per la compilazione del codice.
Charlie,

2

Retina , 63 byte

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

Provalo online! Spiegazione:

.+
$*#<

Converti in unario e suffisso a < .

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

Converti in binario.

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

Una volta tutto il < s hanno raggiunto la sinistra, cancellale tutte.

m`^<
 <

Inserisci uno spazio prima di qualsiasi < s che abbia già raggiunto la sinistra.

(.)<
<$1

Sposta tutte le <s a sinistra di un passo. Risciacqua e ripeti.


2

PowerShell , 100 byte

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

Provalo online!

Ugh, usare convertil binario in PowerShell è così doloroso. Inoltre .lengthy chiama -replacegli 0spazi con, più una lunga .padLeft()chiamata per renderli tutti uguali .length, il tutto si aggiunge a una lunga presentazione.

I suggerimenti sul golf per scendere sotto i 100 sono i benvenuti.


2

PHP, 84 byte

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

Fortunatamente, l'operazione bit lancia il logrisultato a int. float non funzionerebbe qui.

Provalo online .


2

Clojure, 185 byte

(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)))

Versione non golfata:

(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)))

Funzione anonima che accetta l'argomento come elenco. Restituisce le righe come elenco.

Leggendo le altre risposte, scommetto che potrebbe essere più piccolo. clojure.string/replacerichiede una quantità oscena di caratteri per scrivere ..


2

Japt , 33 30 byte

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

Provalo online!

Salvato 3 byte grazie a @Justin Mariner

Spiegazione

¡                              // 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 '*'

È possibile eliminare gli ultimi 3 caratteri per restituire solo una matrice di stringhe e utilizzare il -Rflag (non aggiunto al conteggio dei byte) per vedere l'output unito alla nuova riga: qui .
Justin Mariner,

2

Python 3 , 92 90 byte

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

Provalo online!

Restituisce un elenco di righe. Accatastandoli mostra che si allineano correttamente.

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

La rottura

Converte essenzialmente l'array in binario, quindi sostituisce tutti gli 0 con spazi. Nil numero di spazi viene aggiunto all'inizio di ogni riga in cui N = [length of longest line] - [length of line].

-1 bytes Grazie a Mr. Xoder

Provalo online!


Non è possibile avere spazi iniziali o finali nell'output.
TheLethalCoder il

@TheLethalCoder Oh, deve aver letto male le regole! Grazie per averlo colto.
Graviton,

90 byte , sostituisci '0',' 'con *'0 '.
Mr. Xcoder,

@Mr.Xcoder Ah interesting, would never have thought about that. Thanks!
Graviton

2

Japt, 11 bytes

m¤z3 z ·r0S

Try it online!

Explanation

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

Nice exploit with z3 z. Not sure why y y doesn't work there, I'll look into it later...
ETHproductions

2

Java 7, 130 108 88 bytes

Saved 22 thanks to @TheLethalCoder Saved 20 thanks to @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
Post increment i at b[i] to save a byte. You can keep the output with 1's so no need for the .replace('1','*'). Use Java 8 instead and compile to a lambda to save bytes. If you don't want to do that int[]b saves a byte.
TheLethalCoder

Thank you! Could you please explain what "Post increment i at b[i] to save a byte." means?
Java Gonzar

i++ evaluates i then increments it (whereas ++i does the opposite) so you can move the i++ out of the for loop and use b[i++] instead. Oh and whilst we're at it you only have one line inside your loop so the braces aren't needed.
TheLethalCoder

True! Amazing, thank you
Java Gonzar

2
You can save a few bytes by switching your loop to a foreach loop. for(int x:i) Also, you can use Long.toBinaryString instead of the Integer version to save 3 bytes.
Xanderhall

1

Python 2, 217 bytes

After 2 hours of coding i decided, that numpy is bad idea for this

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()

Usage in Ubuntu

Install numpy

python2 -m pip install numpy

Create file named i with input in format 14 4 6 2

Run

python2 prog.py

1

8th, 232 254 250 bytes

Code

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

Ungolfed version with comments

\ 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 ;

These words must be invoked in sequence (see example)

Usage and examples

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
****
 ***
** *
* **

Or more clearly

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


1

Excel VBA, 170 161 Bytes

Golfed

Anonymous VBE immediate window function that that takes input of format 1 2 3 .. n from range [A1] and outputs the corresponding binary wall to the VBE Immediate window via range [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

Formatted:

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

Full Subroutine that takes input of format Array(1, 2, 3...) and outputs the corresponding binary wall to the VBE Immediate window 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

Charcoal, 20 bytes

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

Try it online! Link is to verbose version of code. Works by manually converting each input number to binary but printing it in right-to-left order. I take the input as a newline terminated string as Charcoal doesn't have a good way of inputting lists otherwise I would write something like this which unfortunately currently takes 21 bytes:

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

Try it online! Link is to verbose version of code. This version vectorises over the input array, although its output is hardcoded to -s which saves a byte.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.