Create a binary wall

33

6

Given an array of positive integers in base 10, where n > 0, output their representation of a binary wall.

How does this work?

  1. Convert each number to it's binary representation.
  2. Pad the representation with leading zeroes to the length of the longest one i.e. 1, 2 -> 1, 10 -> 01, 10.
  3. Create a wall where the 1s are bricks and 0s are missing bricks.

A wall is a block of characters where any printable character represents a brick and a space (32) represents a missing brick. You may choose any character for the brick, it need not be distinct across the wall as long as it isn't a white space character. The missing brick character must be a space. For the example below I have used * for the bricks.

Example

Input:

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

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

Rules

  • Input must be taken in base 10, if your language accepts other bases you may not use them.
  • Leading and trailing new lines are allowed.
  • Input may be taken as a list of integers, separate arguments or any reasonable format.
  • Output may be in any reasonable format: new line separated string, array of lines, 2d array etc.
  • Standard loopholes are disallowed.

Test Cases

Note that in the first test case all of layers have an empty brick at the end.

[ 14, 4, 6, 2 ]

*** 
 *  
 ** 
  * 

[ 1, 2, 4, 8, 16 ]

    *
   * 
  *  
 *   
*

[ 15, 11, 15, 15 ]

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

[ 11, 10, 9, 8 ]

* **
* * 
*  *
*   

This is code golf so shortest code wins!

TheLethalCoder

Posted 2017-07-24T10:31:43.977

Reputation: 6 930

Can the output be an array of lines or a 2d array of chars? – ovs – 2017-07-24T11:23:13.167

@ovs Sorry thought I'd specified that, yes you can output an array or 2d array etc. Any reasonable format. – TheLethalCoder – 2017-07-24T11:26:15.020

In the case of a 2D array, can we use numbers for the bricks instead of characters? e.g. [[1, " ", 1, " "], ...] – Arnauld – 2017-07-24T13:27:03.700

@Arnauld Yeah that seems fine. – TheLethalCoder – 2017-07-24T13:45:16.933

trailing whitespace is allowed? – Giuseppe – 2017-07-24T15:45:21.463

1@Giuseppe New lines only, otherwise it will be confused for empty bricks. – TheLethalCoder – 2017-07-24T15:46:44.670

may not, not cannot :P – Oliver Ni – 2017-07-25T02:50:35.003

What's with the rule about base 10? It's all an int internally anyway, regardless if you parse the number in base 10 or base 2 or base 16… What's the point of this rule? – 2xsaiko – 2017-07-25T17:52:11.893

@therealfarfetchd One of the steps is to convert to base 2, it would be pretty pointless if you already took input in base 2... – TheLethalCoder – 2017-07-26T07:52:38.833

What would be different with for example in Java: Integer.parseInt("14", 10) and Integer.parseInt("E", 16)? They all yield int(14). But now I'm thinking you're thinking of not parsing the number at all, in which case, the rule makes sense. But then, again, when not parsing the number you don't have "an array of positive integers", but an array of strings. That probably just threw me off. I think I get it now though. – 2xsaiko – 2017-07-26T18:12:34.053

Answers

13

MATL, 5 bytes

B42*c

Try it online!

Explanation

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

Posted 2017-07-24T10:31:43.977

Reputation: 87 464

You may choose any character for the brick, it need not be distinct across the wall as long as it isn't a white space character. yeah that means you probably don't need 42* or something... – Erik the Outgolfer – 2017-07-24T12:37:56.177

@EriktheOutgolfer I could choose any other number, but I do need those three bytes I think. – Luis Mendo – 2017-07-24T12:47:04.490

What if there's a 1-byte builtin for 100 or some other number? – Erik the Outgolfer – 2017-07-24T12:51:00.943

11

J, 8 bytes

' *'{~#:

Try it online!

Explanation

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

miles

Posted 2017-07-24T10:31:43.977

Reputation: 15 654

Oh, so #: is why this beats Jelly. – Erik the Outgolfer – 2017-07-24T13:38:46.550

9

Jelly, 9 bytes

Bo⁶Uz⁶ZUY

Try it online!

EDIT: HOW J BEAT JELLY DAT IMPOSSIBLE >_<

Erik the Outgolfer

Posted 2017-07-24T10:31:43.977

Reputation: 38 134

8

Octave, 22 bytes

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

Try it online

Explanation:

Saved some bytes thanks to Luis Mendo! Also, I didn't notice that I could choose which character to build the wall with, not only *.

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

Or with de2bi:

Explanation:

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

The following works on TIO, for 7 bytes more:

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

Try it here

Stewie Griffin

Posted 2017-07-24T10:31:43.977

Reputation: 43 471

5

Python 3, 88 84 71 74 72 bytes

A lambda that returns a list of Strings, representing each line.

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

Try it online! (link to the newline separated version)

Explanation

  • lambda n: - Creates an (anonymous) lambda, with a parameter n. Returns implicitly.

  • [...] - Creates a list comprehension.

  • bin(x)[2:] - Gets the binary representations of the numbers.

  • .replace(*'0 ') - Replaces all the occurrences of 0 with a space.

  • .rjust(len(bin(max(n)))-2) - Pads the binary representations to the length of the longest one.

  • for x in n - Iterates through n, with the variable x.


Changelog

  • -1 - 3 bytes thanks to @Rod, -(...)+2 = 2-(...), use of rjust()

  • Added a version with bin() instead, that was invalid since it didn't work for 1 and 2.

  • Fixed the bug above using format().

  • Changed return type to list of Strings, because it was allowed by the OP.

  • Fixed yet another bug using rjust() and switching back to bin(), spotted and fixed by @Rod.

Mr. Xcoder

Posted 2017-07-24T10:31:43.977

Reputation: 39 774

5

JavaScript (ES6), 81 79 bytes

Saved 2 bytes by using numbers instead of characters for the bricks, as suggested by Rick Hitchcock

Returns a 2D array with 1's for the bricks.

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)

Test cases

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)

format = a => a.map(s => s.join``).join`\n`

console.log(format(f([ 14, 4, 6, 2 ])))
console.log(format(f([ 1, 2, 4, 8, 16 ])))
console.log(format(f([ 15, 11, 15, 15 ])))
console.log(format(f([ 11, 10, 9, 8 ])))

Arnauld

Posted 2017-07-24T10:31:43.977

Reputation: 111 334

5

Haskell, 76 75 74 bytes

f x|all(<1)x=x>>[""]|a<-f$map(`div`2)x=zipWith(++)a$map(cycle[" ","*"]!!)x

Try it online!

Post Rock Garf Hunter

Posted 2017-07-24T10:31:43.977

Reputation: 55 382

4

Ruby, 63 59 bytes

-4 bytes with help from Alexis Andersen

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

Try it online!

daniero

Posted 2017-07-24T10:31:43.977

Reputation: 17 193

1you don't need the 0 in the string format. you could shave a byte by replacing n.max.to_s(2).size with ('%b'%n.max).size and you don't actually need to replace the 1 with * – Alexis Andersen – 2017-07-24T17:51:37.930

@AlexisAndersen thanks :) – daniero – 2017-07-24T19:48:07.797

4

05AB1E, 9 bytes

bí.Bí»0ð‡

Try it online!

Erik the Outgolfer

Posted 2017-07-24T10:31:43.977

Reputation: 38 134

Beat me by 38 seconds. I had b0ð:í.Bí» for 9 bytes as well. – Riley – 2017-07-24T13:09:17.810

4

R, 87 88 bytes

Wall blocks represented by an 8, because, well lots of eights.

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

Try it online!

Input integer list is converted to array of bits which are trimmed of trailing 0 bits and reversed.

The reduced array is then output using write and a column width which was determined when the array was trimmed.

ifelse() is the only IF option that works on vectors unfortunately.

MickyT

Posted 2017-07-24T10:31:43.977

Reputation: 11 735

@Vlo pointed out you can use 1 rather than "" for the output file in write. – Giuseppe – 2018-03-12T14:54:15.197

@Giuseppe thanks for the tip – MickyT – 2018-03-12T17:54:17.897

3

APL (Dyalog), 30 22 20 14 bytes

Saved 6 bytes thanks to @Adám

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

Try it online!

(assumes ⎕IO←0 as this is default on many machines)

This takes input as an array and returns a matrix with *s and s.

Explanation

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

user41805

Posted 2017-07-24T10:31:43.977

Reputation: 16 320

Save 6 bytes with ' *'[⍉2⊥⍣¯1⊢⎕]

– Adám – 2017-07-24T12:18:13.953

@Adám Thanks for the tips, I didn't know I could remove the ¨. – user41805 – 2017-07-24T13:01:41.033

3

Mathematica, 40 bytes

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

Bricks are 1s

Mathematica, 48 bytes

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

Bricks are #

J42161217

Posted 2017-07-24T10:31:43.977

Reputation: 15 931

You should only need one slash in the //.. (/. means "replace once", //. means "keep doing the replacement until the thing stops changing".) – Not a tree – 2017-07-24T11:25:53.460

ok-fixed-thanks – J42161217 – 2017-07-24T13:26:30.957

You don't need the space after the comma in the IntegerDigits function. – Mark S. – 2017-07-25T00:14:11.673

yes,I know,this happens when you copy/paste from notebook.fixed – J42161217 – 2017-07-25T00:17:38.720

3

Python 2, 77 bytes

lambda k:[[' *'[i&2**y>0]for y in range(len(bin(max(k)))-3,-1,-1)]for i in k]

Try it online!

ovs

Posted 2017-07-24T10:31:43.977

Reputation: 21 408

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

Uses 1 for the brick piece, assumes input comes from table @

Ungolfed, with some explanation

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

Posted 2017-07-24T10:31:43.977

Reputation: 653

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

Try it online!

The byte count includes 41 bytes from using System.Linq;using C=System.Convert;. Uses 1 as character for the wall. Nonetheless, this is way too long even for C#...

Charlie

Posted 2017-07-24T10:31:43.977

Reputation: 11 448

Place in namespace System.Linq{} to save some bytes. Is a.Max() guaranteed to be true (I'm sure it is I'm just not the smartest with binary :P)? Would class Convert{} save any bytes? – TheLethalCoder – 2017-07-24T11:17:50.670

1If I place the program in a given namespace, shouldn't I submit the whole program instead of just a lambda? I'm not sure about the rules for that... – Charlie – 2017-07-24T11:23:26.440

I've usually just placed in namespace with lambda. I don't think there's ever been a question about it and it is in the C# tips page. – TheLethalCoder – 2017-07-24T11:24:56.677

I don't think this is valid, as you can't compile it without using static imports. – MetaColon – 2017-07-24T12:26:50.970

@MetaColon you can check the whole code in the TIO link, see that it does not use static imports, but an alias for a certain type. – Charlie – 2017-07-24T12:30:22.673

@CarlosAlejo actually I meant alias using directives. – MetaColon – 2017-07-24T12:34:58.943

2@MetaColon that's the reason why I added the bytes in using System.Linq;using C=System.Convert; to byte count, as those two using directives are needed for the code to compile. – Charlie – 2017-07-24T12:40:40.930

I know I'm late, but I think saving Convert.ToString(int, int) to a lambda might make this shorter. e.g. var b = (int n) => System.Convert.ToString(n, 2);, making the using unnecassry and letting you do: a=>a.Select(n=>b(n).Replace("0"," ").PadLeft(b(a.Max(),2).Length)) – Pharap – 2017-07-31T03:53:10.867

2

Retina, 63 bytes

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

Try it online! Explanation:

.+
$*#<

Convert to unary, and suffix a <.

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

Convert to binary.

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

Once all the <s have reached the left, delete them all.

m`^<
 <

Insert a space before any <s that have already reached the left.

(.)<
<$1

Move all the <s left one step. Rinse and repeat.

Neil

Posted 2017-07-24T10:31:43.977

Reputation: 95 035

2

PowerShell, 100 bytes

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

Try it online!

Ugh, converting to binary in PowerShell is so painful. Plus .lengthy calls to -replace the 0 with spaces, plus a long .padLeft() call to make them all the same .length, all adds up to a long submission.

Golfing suggestions to get below 100 are welcome.

AdmBorkBork

Posted 2017-07-24T10:31:43.977

Reputation: 41 581

2

Japt, 33 30 bytes

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

Try it online!

Saved 3 bytes thanks to @Justin Mariner

Explanation

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

Posted 2017-07-24T10:31:43.977

Reputation: 1 277

You can drop the last 3 chars to just return an array of strings, and use the -R flag (not added to byte count) to see the newline-joined output: here.

– Justin Mariner – 2017-07-25T10:28:20.500

2

PHP, 84 bytes

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

Luckily, the bit operation casts the log result to int. float wouldn´t work here.

Try it online.

Titus

Posted 2017-07-24T10:31:43.977

Reputation: 13 814

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

Try it online!

Returns a list of lines. Stacking them up shows they do indeed align properly.

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

The breakdown

Essentially converts the array to binary, then replaces all 0's with spaces. N number of spaces are added to the front of each line where N = [length of longest line] - [length of line].

-1 bytes Thanks to Mr. Xoder

Try it online!

Graviton

Posted 2017-07-24T10:31:43.977

Reputation: 2 295

You can't have leading or trailing spaces in the output. – TheLethalCoder – 2017-07-25T08:58:00.850

@TheLethalCoder Oh, must have misread the rules! Thanks for catching that. – Graviton – 2017-07-25T09:02:30.043

90 bytes, replace '0',' ' with *'0 '. – Mr. Xcoder – 2017-07-25T10:18:44.643

@Mr.Xcoder Ah interesting, would never have thought about that. Thanks! – Graviton – 2017-07-25T22:17:53.797

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

Ungolfed version:

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

Anonymous function that takes the argument as a list. Returns the lines as list.

Reading the other answers, I bet it could be smaller. clojure.string/replace takes an obscene amount of chars to write..

Joshua

Posted 2017-07-24T10:31:43.977

Reputation: 231

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

Java Gonzar

Posted 2017-07-24T10:31:43.977

Reputation: 173

1Post 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 – 2017-07-25T12:24:01.163

Thank you! Could you please explain what "Post increment i at b[i] to save a byte." means? – Java Gonzar – 2017-07-25T12:35:24.553

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 – 2017-07-25T12:37:37.837

True! Amazing, thank you – Java Gonzar – 2017-07-25T12:40:11.097

2You 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 – 2017-07-26T14:16:31.053

Great Xanderhall! Thank you :) – Java Gonzar – 2017-07-27T07:27:24.360

Might want to actually make Java 7 link to something. – Zacharý – 2017-07-31T16:40:18.830

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

Justin Mariner

Posted 2017-07-24T10:31:43.977

Reputation: 4 746

Nice exploit with z3 z. Not sure why y y doesn't work there, I'll look into it later... – ETHproductions – 2017-07-29T23:11:09.117

1

Pyth, 16 bytes

j_MC.tm_X.Bd\0\ 

Try it here. Mind the trailing space.

Erik the Outgolfer

Posted 2017-07-24T10:31:43.977

Reputation: 38 134

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

Евгений Новиков

Posted 2017-07-24T10:31:43.977

Reputation: 987

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

Taylor Scott

Posted 2017-07-24T10:31:43.977

Reputation: 6 709

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

Chaos Manor

Posted 2017-07-24T10:31:43.977

Reputation: 521

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.

Neil

Posted 2017-07-24T10:31:43.977

Reputation: 95 035