38
\$\begingroup\$

According to me, a tornado looks like this:

########
#######
 ######
  #####
   ####
   ###
    ##
     #

This tornado starts out with width n, and on each next line, a character is removed from either the left or the right, depending on the input.

Input

The input will be a list of some sort of any two unique values (a string of two unique characters works too), and an optional positive integer to indicate the starting width. If the optional integer is not taken, then the starting width is 1 greater than the length of the list. Let the starting width be n.

How to make a tornado

In my example, I choose my list to contain 1s and 0s, though you may choose any two distinct constant values, or a string of any two distinct constant characters.

The first row will consist of n non-whitespace characters (you may choose any consistent character; I choose # for my example).

Then, for each number in the list, if the number is 0, remove the left character and create a new row; if it's a 1, remove the right character and create a new row.

Thus, the above tornado is the output for 8, [1, 0, 0, 0, 1, 0, 0].

Output

The output can be a list of strings, a list of lists of characters, or a multiline string. Trailing whitespace on each line is allowed, and a trailing newline at the end is allowed.

Test Cases

These testcases include the starting width and use lists of 1, 0.

5, [1,0,0,1]

#####
####
 ###
  ##
  #

10, [1,0,0,1,0,1,0,0,1]

##########
#########
 ########
  #######
  ######
   #####
   ####
    ###
     ##
     #

7, [1,1,1,1,1,1]

#######
######
#####
####
###
##
#

Rules

  • Standard loopholes apply
  • Shortest code in bytes wins!
  • Background doesn't have to be a space (I forgot to specify this earlier).
  • Your language only has to support numbers (widths) that it can handle, but if your interpreter were rewritten with a larger number size, it has to theoretically work.

Reference Implementation

\$\endgroup\$
9
  • 3
    \$\begingroup\$ It seems from your examples that the starting with is always going to be 1 greater than the length of the list. Could we have an example where this isn't so? Can the starting width be less than the length of the list? \$\endgroup\$
    – Charlie
    Commented Jul 20, 2017 at 20:02
  • \$\begingroup\$ @CarlosAlejo No... That doesn't make sense then because then you won't have enough elements to remove at the end... \$\endgroup\$
    – hyperneutrino
    Commented Jul 20, 2017 at 20:15
  • 8
    \$\begingroup\$ The glasses that @HyperNeutrino used to see his first tornado: i.imgur.com/TzMm94a.png \$\endgroup\$ Commented Jul 21, 2017 at 2:04
  • \$\begingroup\$ @MagicOctopusUrn...lol \$\endgroup\$
    – hyperneutrino
    Commented Jul 21, 2017 at 2:11
  • \$\begingroup\$ May the input and output be reversed? \$\endgroup\$
    – user
    Commented Jan 22, 2021 at 20:55

28 Answers 28

10
\$\begingroup\$

Python 2, 66 59 bytes

-7 bytes thanks to Arnold Palmer

x,z=input()
for i in range(x):print' '*sum(z[:i])+'#'*(x-i)

Try it online!

0 to remove from the right, 1 to remove from the left

\$\endgroup\$
3
  • 1
    \$\begingroup\$ ninja'd me :((( \$\endgroup\$ Commented Jul 20, 2017 at 19:58
  • \$\begingroup\$ Same here man :/ \$\endgroup\$ Commented Jul 20, 2017 at 19:59
  • \$\begingroup\$ Save 7 bytes by replacing len(z)+1 with x if "optional positive integer" means you don't have to use it. The wording of the question makes it sound like this is allowed since it says "If the optional integer is not taken" versus "If the optional integer is not given". \$\endgroup\$ Commented Jul 20, 2017 at 20:03
9
\$\begingroup\$

V, 15, 12 bytes

ïÀé#òÙxHxG@"

Try it online!

l for right, (makes perfect sense, doesn't it?) and > for left.

\$\endgroup\$
0
7
\$\begingroup\$

vim, 85 82 bytes

o"cp:s/#/ <C-v><CR>0"cy$<ESC>"ayy7hR$/<ESC>"bdd:s/[][, ]\+/<C-v><CR>@/g<CR>ggAa#<C-v><ESC><ESC>^D@"^"cy$:2,$:norm D@"

<ESC> is 0x1B, <CR> is 0x0D, <C-v> is 0x16. And <ESC>OH is a multibyte sequence representing the HOME key.

The input uses a as the "remove left" value and b as the "remove right" value.

" @a will remove from the left; @b will remove from the right.
o"cp:s/#/ <C-v><CR>0"cy$<ESC>"ayy
7hR$/<ESC>"bdd

" split the input into digestible chunks
:s/[][, ]\+/<C-v><CR>@/g<CR>
gg

" Create the first line
Aa#<C-v><ESC><ESC>
^D
@"^"cy$

" Create tornado
:2,$:norm D@"

No TIO link, unfortunately. I couldn't get it working under V. Test by copying code into tornado.vim (replacing <ESC>, etc with their actual bytes) and running as follows:

$ echo '8, [b, a, a, a, b, a, a]' > a.txt
$ { cat tornado.vim; echo ':wq'; } | vim a.txt
$ cat a.txt

-3 bytes due to Neil's suggestion.

\$\endgroup\$
4
  • \$\begingroup\$ Can you not use ^ instead of ␛OH? \$\endgroup\$
    – Neil
    Commented Jul 21, 2017 at 9:19
  • \$\begingroup\$ @Neil ^ goes to the first non-blank character. ␛OH goes to the first character. \$\endgroup\$
    – Ray
    Commented Jul 24, 2017 at 21:28
  • 1
    \$\begingroup\$ Ah, sorry, I meant 0 didn't I... \$\endgroup\$
    – Neil
    Commented Jul 24, 2017 at 21:30
  • \$\begingroup\$ @Neil In that case, yes, I should be doing that. Thanks. \$\endgroup\$
    – Ray
    Commented Jul 24, 2017 at 21:40
5
\$\begingroup\$

05AB1E, 11 9 bytes

-2 bytes thanks to Erik the Outgolfer

0×=²v¨yú=

Remove from left: 1
Remove from right: 0

Try it online!

0×        # Make a string of n 0s
  =       # Print without popping
   ²v     # For each character in input (call it y):
     ¨    #   Remove the last character of the current string
      yú  #   Pad with y spaces
        = #   Print without popping
\$\endgroup\$
2
  • \$\begingroup\$ 0×ηsηO has so much potential but I can't figure it out under 11 bytes. \$\endgroup\$ Commented Jul 21, 2017 at 1:58
  • \$\begingroup\$ Keep the latter version and replace ðy×ì with for -2. \$\endgroup\$ Commented Jul 21, 2017 at 8:38
4
\$\begingroup\$

Retina, 30 28 bytes

.?
$`#$&$'¶
T`d`#`#.*
T`d` _

Try it online! Takes just a string of 0s and 1s and calculates the width based on the string. Explanation: The first stage takes the input string and duplicates it once for each boundary point, inserting a # at that point. The second stage then changes all the digits after the # to more #s, creating the triangle. The third stange then deletes all the remaining ones and changes the zeros to spaces which results in the torndao's "wobble".

\$\endgroup\$
3
\$\begingroup\$

Python 2, 58 57 bytes

edit: saved 1 byte thanks to xnor

l,a=input()
s="#"*l
for i in a+[0]:print s;s=" "*i+s[:-1]

Try it online!

1 to remove from the left, 0 to remove from the right.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I think you can do s=" "*i+s[:-1] with left and right swapped. \$\endgroup\$
    – xnor
    Commented Jul 20, 2017 at 21:38
3
\$\begingroup\$

Perl, 43 bytes

42 bytes code + 1 for -l.

$_="#"x<>;do{print}while<>|0?s/#$//:s/#/ /

Try it online!

\$\endgroup\$
3
\$\begingroup\$

R, 85 82 bytes

3 bytes saved thanks to Giuseppe

function(n,l)for(k in 1:n)cat(rep(" ",sum(c(0,l)[1:k])),rep("%",n-k+1),"
",sep="")

Try it online!

Explanation:

function(n,l){
  for(k in 1:n){                      # Proceed line by line
    cat(                              # Concatenate...
        rep(" ",sum(c(0,l)[1:k])),    # ...required number of leading spaces,...
        rep("%",n-k+1),               # ...required number of tornado characters...
        "\n",                         # ...and a new line.
        sep=""                        # Join without spaces
        )
  }
}
\$\endgroup\$
2
  • \$\begingroup\$ I knew making a matrix wasn't the best option! \$\endgroup\$
    – Giuseppe
    Commented Jul 21, 2017 at 13:21
  • 1
    \$\begingroup\$ 82 bytes -- shaved off the {} and used a literal newline instead of '\n' \$\endgroup\$
    – Giuseppe
    Commented Jul 21, 2017 at 13:23
3
\$\begingroup\$

Haskell, 50 bytes

h n=scanl(\s i->[(' ':),id]!!i$init s)$'#'<$[1..n]

Try it online!

If the input list can be a list of function names, we can save a byte

Haskell, 49 bytes

f=id
g=(' ':)
h n=scanl(flip id.init)$'#'<$[1..n]

Usage example: h 5 [g,f,f,g].

Try it online!

How it works:

           '#'<$[1..n]   -- build the first line of the tornado, i.e. n times '#'
scanl(    )              -- repeatedly apply the given function to the starting
                         -- value and the next element of the input list and
                         -- return a list of the intermediate results
  \s i->                 -- the function takes a string s and a number i
            init s       -- and first drops the last element of s
      [    ]!!i          -- and then picks and apply a funtion from the list
        (' ':)           --  i = 0:  prepend a space
        id               --  i = 1:  do nothing
\$\endgroup\$
3
\$\begingroup\$

ArnoldC, 3132 bytes

ArnoldC doesn't have string concatenations, so this builds a tornado out of 8s and uses 1s to space it out. ArnoldC also only supports up to 16-bit integers, so it overflows with input longer than 7 digits. (So it will only make mini-tornadoes)

1 is left, any other digit is right (although I wouldn't recommend 0, since you can't start with that.)

Input: 1221122

Output:

88888888
18888888
18888881
18888811
11888811
11188811
11188111
11181111

Golfed code:

IT'S SHOWTIME
HEY CHRISTMAS TREE d
YOU SET US UP 0
HEY CHRISTMAS TREE e
YOU SET US UP 0
HEY CHRISTMAS TREE m
YOU SET US UP 0
GET YOUR ASS TO MARS m
DO IT NOW
I WANT TO ASK YOU A BUNCH OF QUESTIONS AND I WANT TO HAVE THEM ANSWERED IMMEDIATELY
HEY CHRISTMAS TREE l
YOU SET US UP 0
GET YOUR ASS TO MARS l
DO IT NOW g m
DO IT NOW h l m
YOU HAVE BEEN TERMINATED
LISTEN TO ME VERY CAREFULLY g
I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE m
GIVE THESE PEOPLE AIR
HEY CHRISTMAS TREE i
YOU SET US UP 2
HEY CHRISTMAS TREE n
YOU SET US UP m
STICK AROUND n
GET TO THE CHOPPER n
HERE IS MY INVITATION n
HE HAD TO SPLIT 10
ENOUGH TALK
BECAUSE I'M GOING TO SAY PLEASE n
GET TO THE CHOPPER i
HERE IS MY INVITATION i
GET UP 1
ENOUGH TALK
YOU HAVE NO RESPECT FOR LOGIC
CHILL
I'LL BE BACK i
HASTA LA VISTA, BABY
LISTEN TO ME VERY CAREFULLY h
I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE l
I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE m
GIVE THESE PEOPLE AIR
HEY CHRISTMAS TREE o
YOU SET US UP -2
GET TO THE CHOPPER o
HERE IS MY INVITATION o
GET UP l
ENOUGH TALK
HEY CHRISTMAS TREE k
YOU SET US UP 1
STICK AROUND o
GET TO THE CHOPPER k
HERE IS MY INVITATION k
YOU'RE FIRED 10
ENOUGH TALK
GET TO THE CHOPPER o
HERE IS MY INVITATION o
GET DOWN 1
ENOUGH TALK
CHILL
HEY CHRISTMAS TREE p
YOU SET US UP 0
HEY CHRISTMAS TREE f
YOU SET US UP 0
HEY CHRISTMAS TREE i
YOU SET US UP 0
HEY CHRISTMAS TREE q
YOU SET US UP l
HEY CHRISTMAS TREE d
YOU SET US UP 0
HEY CHRISTMAS TREE e
YOU SET US UP 1
HEY CHRISTMAS TREE a
YOU SET US UP 0
HEY CHRISTMAS TREE b
YOU SET US UP 0
HEY CHRISTMAS TREE c
YOU SET US UP l
STICK AROUND q
GET TO THE CHOPPER i
HERE IS MY INVITATION 0
ENOUGH TALK
GET TO THE CHOPPER a
HERE IS MY INVITATION d
ENOUGH TALK
GET TO THE CHOPPER b
HERE IS MY INVITATION e
ENOUGH TALK
GET TO THE CHOPPER c
HERE IS MY INVITATION l
ENOUGH TALK
STICK AROUND c
BECAUSE I'M GOING TO SAY PLEASE a
GET TO THE CHOPPER i
HERE IS MY INVITATION i
GET UP 1
YOU'RE FIRED 10
ENOUGH TALK
GET TO THE CHOPPER a
HERE IS MY INVITATION a
GET DOWN 1
ENOUGH TALK
BULLSHIT
GET TO THE CHOPPER f
HERE IS MY INVITATION b
LET OFF SOME STEAM BENNET c
ENOUGH TALK
BECAUSE I'M GOING TO SAY PLEASE f
GET TO THE CHOPPER i
HERE IS MY INVITATION i
GET UP 1
YOU'RE FIRED 10
ENOUGH TALK
BULLSHIT
GET TO THE CHOPPER i
HERE IS MY INVITATION i
GET UP 8
YOU'RE FIRED 10
ENOUGH TALK
YOU HAVE NO RESPECT FOR LOGIC
YOU HAVE NO RESPECT FOR LOGIC
GET TO THE CHOPPER c
HERE IS MY INVITATION c
GET DOWN 1
ENOUGH TALK
CHILL
GET TO THE CHOPPER i
HERE IS MY INVITATION i
HE HAD TO SPLIT 10
ENOUGH TALK
TALK TO THE HAND i
GET TO THE CHOPPER q
HERE IS MY INVITATION q
GET DOWN 1
ENOUGH TALK
GET TO THE CHOPPER p
HERE IS MY INVITATION m
HE HAD TO SPLIT k
I LET HIM GO 10
ENOUGH TALK
GET TO THE CHOPPER k
HERE IS MY INVITATION k
HE HAD TO SPLIT 10
ENOUGH TALK
GET TO THE CHOPPER f
HERE IS MY INVITATION p
YOU ARE NOT YOU YOU ARE ME 1
ENOUGH TALK
BECAUSE I'M GOING TO SAY PLEASE f
GET TO THE CHOPPER d
HERE IS MY INVITATION d
GET UP 1
ENOUGH TALK
BULLSHIT
GET TO THE CHOPPER e
HERE IS MY INVITATION e
GET UP 1
ENOUGH TALK
YOU HAVE NO RESPECT FOR LOGIC
CHILL
I'LL BE BACK i
HASTA LA VISTA, BABY

Try it online!

Ungolfed code (5178 bytes):

IT'S SHOWTIME
    HEY CHRISTMAS TREE left
        YOU SET US UP 0
    HEY CHRISTMAS TREE right
        YOU SET US UP 0
    HEY CHRISTMAS TREE input
        YOU SET US UP 0
        GET YOUR ASS TO MARS input
        DO IT NOW
        I WANT TO ASK YOU A BUNCH OF QUESTIONS AND I WANT TO HAVE THEM ANSWERED IMMEDIATELY
    HEY CHRISTMAS TREE width
    YOU SET US UP 0
    GET YOUR ASS TO MARS width
    DO IT NOW calcwidth input
    DO IT NOW buildline width input
YOU HAVE BEEN TERMINATED

LISTEN TO ME VERY CAREFULLY calcwidth
    I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE input
    GIVE THESE PEOPLE AIR
    HEY CHRISTMAS TREE result
    YOU SET US UP 2
    HEY CHRISTMAS TREE calc
    YOU SET US UP input
    STICK AROUND calc
        GET TO THE CHOPPER calc
        HERE IS MY INVITATION calc
        HE HAD TO SPLIT 10
        ENOUGH TALK
        BECAUSE I'M GOING TO SAY PLEASE calc
            GET TO THE CHOPPER result
        HERE IS MY INVITATION result
        GET UP 1
        ENOUGH TALK
    YOU HAVE NO RESPECT FOR LOGIC
    CHILL
    I'LL BE BACK result
HASTA LA VISTA, BABY

LISTEN TO ME VERY CAREFULLY buildline
    I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE width
    I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE input
    GIVE THESE PEOPLE AIR

    HEY CHRISTMAS TREE ctr
        YOU SET US UP -2
        GET TO THE CHOPPER ctr
            HERE IS MY INVITATION ctr
            GET UP width
        ENOUGH TALK
    HEY CHRISTMAS TREE mask
        YOU SET US UP 1
        STICK AROUND ctr
            GET TO THE CHOPPER mask
                HERE IS MY INVITATION mask
                YOU'RE FIRED 10
            ENOUGH TALK
            GET TO THE CHOPPER ctr
                HERE IS MY INVITATION ctr
                GET DOWN 1
            ENOUGH TALK
        CHILL
    HEY CHRISTMAS TREE digit
        YOU SET US UP 0
    HEY CHRISTMAS TREE decider
        YOU SET US UP 0
    HEY CHRISTMAS TREE result
        YOU SET US UP 0
    HEY CHRISTMAS TREE lines
        YOU SET US UP width
    HEY CHRISTMAS TREE left
        YOU SET US UP 0
    HEY CHRISTMAS TREE right
        YOU SET US UP 1
    HEY CHRISTMAS TREE leftcounter
        YOU SET US UP 0
    HEY CHRISTMAS TREE rightcounter
        YOU SET US UP 0
    HEY CHRISTMAS TREE widthcounter
    YOU SET US UP width
    STICK AROUND lines
        GET TO THE CHOPPER result
            HERE IS MY INVITATION 0
        ENOUGH TALK
        GET TO THE CHOPPER leftcounter
            HERE IS MY INVITATION left
        ENOUGH TALK
        GET TO THE CHOPPER rightcounter
            HERE IS MY INVITATION right
        ENOUGH TALK
        GET TO THE CHOPPER widthcounter
            HERE IS MY INVITATION width
        ENOUGH TALK
        STICK AROUND widthcounter
            BECAUSE I'M GOING TO SAY PLEASE leftcounter
                GET TO THE CHOPPER result
                    HERE IS MY INVITATION result
                    GET UP 1
                    YOU'RE FIRED 10
                ENOUGH TALK
                GET TO THE CHOPPER leftcounter
                    HERE IS MY INVITATION leftcounter
                    GET DOWN 1
                ENOUGH TALK
            BULLSHIT
                GET TO THE CHOPPER decider
                    HERE IS MY INVITATION rightcounter
                    LET OFF SOME STEAM BENNET widthcounter
                ENOUGH TALK
                BECAUSE I'M GOING TO SAY PLEASE decider
                    GET TO THE CHOPPER result
                        HERE IS MY INVITATION result
                        GET UP 1
                        YOU'RE FIRED 10
                    ENOUGH TALK
                BULLSHIT
                    GET TO THE CHOPPER result
                        HERE IS MY INVITATION result
                        GET UP 8
                        YOU'RE FIRED 10
                    ENOUGH TALK
                YOU HAVE NO RESPECT FOR LOGIC
            YOU HAVE NO RESPECT FOR LOGIC

            GET TO THE CHOPPER widthcounter
                HERE IS MY INVITATION widthcounter
                GET DOWN 1
            ENOUGH TALK
        CHILL
        GET TO THE CHOPPER result
            HERE IS MY INVITATION result
            HE HAD TO SPLIT 10
        ENOUGH TALK
        TALK TO THE HAND result
        GET TO THE CHOPPER lines
            HERE IS MY INVITATION lines
            GET DOWN 1
        ENOUGH TALK
        GET TO THE CHOPPER digit
            HERE IS MY INVITATION input
            HE HAD TO SPLIT mask
            I LET HIM GO 10
        ENOUGH TALK
        GET TO THE CHOPPER mask
            HERE IS MY INVITATION mask
            HE HAD TO SPLIT 10
        ENOUGH TALK
        GET TO THE CHOPPER decider
            HERE IS MY INVITATION digit
            YOU ARE NOT YOU YOU ARE ME 1
        ENOUGH TALK
        BECAUSE I'M GOING TO SAY PLEASE decider
            GET TO THE CHOPPER left
                HERE IS MY INVITATION left
                GET UP 1
            ENOUGH TALK
        BULLSHIT
            GET TO THE CHOPPER right
                HERE IS MY INVITATION right
                GET UP 1
            ENOUGH TALK
        YOU HAVE NO RESPECT FOR LOGIC
    CHILL
    I'LL BE BACK result
HASTA LA VISTA, BABY
\$\endgroup\$
5
  • 1
    \$\begingroup\$ Unfortunately, I don't think this answer is valid because it restricts the input too much and modifies the output in a way that's not permitted (using a non-whitespace background). Sorry! \$\endgroup\$
    – hyperneutrino
    Commented Jul 21, 2017 at 21:30
  • 1
    \$\begingroup\$ @HyperNeutrino Fair enough, this is as good as you can get from ArnoldC. \$\endgroup\$ Commented Jul 21, 2017 at 21:32
  • \$\begingroup\$ That's unfortunate. Sorry to waste your time and effort, but I believe you'll have to delete this as it is invalid by the challenge specifications. You can ask on Meta if you believe that this is the wrong choice and the community can decide there what to do. Thanks :) \$\endgroup\$
    – hyperneutrino
    Commented Jul 21, 2017 at 21:41
  • 2
    \$\begingroup\$ @HyperNeutrino I'm not convined ArnoldC is automatically invalid: it works for the entire range of valid integers supported by ArnoldC, and is not "abusing" it by using a smaller space: If you wrote in 32 bit support for ArnoldC, my answer would work without change at that precision. The rules specify no requirement for padding characters, nor minimum height tornado which must be achievable. But I'll open a question on meta if you'd prefer. \$\endgroup\$ Commented Jul 21, 2017 at 21:57
  • 1
    \$\begingroup\$ You're right. Fair enough, carry on; I misjudged. Nice answer :) \$\endgroup\$
    – hyperneutrino
    Commented Jul 21, 2017 at 22:05
3
\$\begingroup\$

C, 68 63 62 bytes

s;f(w,i)int*i;{for(;w;s+=*i++)printf("%*s%0*d\n",s,"",w--,0);}

This makes use of the dynamic field width specification in a printf() format string. The function is called like this:

#include <stdio.h>

s;f(w,i)int*i;{for(;w;s+=*i++)printf("%*s%0*d\n",s,"",w--,0);}

int main() {
    f(8, (int[]){0, 1, 1, 1, 0, 1, 1});
}

As suggested by @EasyasPi, this swaps the meaning of zero and one in the control string to save a negation in the loop increment expression. Which is fine by the "you may choose any two distinct constant values" rule.

\$\endgroup\$
2
  • \$\begingroup\$ Save 5 bytes by removing int s=0; and putting s; before the f(w,i). Like so \$\endgroup\$
    – MD XF
    Commented Jul 21, 2017 at 22:10
  • \$\begingroup\$ -1 byte if you invert the 1 and 0 function in the array (it is allowed in the rules) \$\endgroup\$
    – EasyasPi
    Commented Dec 31, 2020 at 2:59
3
\$\begingroup\$

J, 32 19 bytes

' #'#~0(,.#\.)@,+/\

Try it online!

-13 thanks to miles

Very belated update...

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 19 bytes ' #'#~0(,.#\.)@,+/\, where the input is inverted from the sample since the challenge allows you to choose the two distinct values. \$\endgroup\$
    – miles
    Commented Jul 21, 2017 at 12:48
  • \$\begingroup\$ @miles ty for this and your other comment. really appreciate them and please keep them coming. \$\endgroup\$
    – Jonah
    Commented Jul 21, 2017 at 14:53
2
\$\begingroup\$

R, 116 109 102 bytes

-5 bytes thanks to user2390246 (and another 2 I saved myself)

Outgolfed by user2390246

function(n,l){k=cumsum
m=matrix(' ',n,n)
for(i in 1:n)m[k(c(1,!l))[i]:k(c(n,-l))[i],i]='#'
write(m,'',n,,'')}

Try it online!

Returns an anonymous function that takes n and a vector l with 0 for removing from the left and 1 for removing from the right, and prints the result to console with the right formatting.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can save a bit in calculating the end of the line since you know the number of #s will be n-i+1: Try it online! Though there's a slightly better approach if you just print line by line rather than constructing a matrix: codegolf.stackexchange.com/a/133720/66252 \$\endgroup\$ Commented Jul 21, 2017 at 13:08
  • \$\begingroup\$ @user2390246 very nice! I managed to shave off another pair of bytes as well :) \$\endgroup\$
    – Giuseppe
    Commented Jul 21, 2017 at 13:20
2
\$\begingroup\$

Japt, 14 13 bytes

-1 byte thanks to @ETH

å+ uP £X+QpV´

Input is the array, then the size. Array values are "" or " ", which represent removing from the right or left, respectively. Uses " instead of # and returns as an array of strings.

The idea here was to first create an array of the left padding for each line, hence the input strings. Then, each line gets the "s added, using the fact that the amount of "s decreases by 1 each time.

Try it online!

These all use the -R flag to format the output by joining it with newlines.

Explanation

å+ uP £X+QpYnV

Implicit: U = input array, V = input number.

å+ uP

Cumulatively reduce the input array (å) with string concatenation (+). This results in the array of each intermediate value of the reduction. Then, prepend (u) an empty string (P) to the array.

£X+

Map £ each value to itself (X) concatenated with...

QpV´

The quote character (Q) repeated (p) V-- () times. This also decrements V each time.

\$\endgroup\$
2
  • \$\begingroup\$ Good one. I think you can save a byte by changing YnV to \$\endgroup\$ Commented Jul 21, 2017 at 20:52
  • \$\begingroup\$ @ETHproductions Awesome, thanks! I totally forgot about using ++ or -- in Japt. \$\endgroup\$ Commented Jul 21, 2017 at 21:01
2
\$\begingroup\$

K (ngn/k), 22 19 bytes

{(-x,x-\y)$|,\x#$0}

Try it online!

Takes two args: the starting width (x), and the list of values (y). Returns a list of strings, with "0" in place of "#".

  • x#$0 initialize a string with x copies of "0", e.g. "00000"
  • |,\ get the reversed prefixes of that string, e.g. ("00000";"0000";"000";"00";,"0")
  • (-x,x-\y) determine how long each line of the output should be (with no trailing spaces) and negate it, e.g. -5 -4 -4 -4 -3
  • (...)$... left-pad each line (with spaces) to its proper length
\$\endgroup\$
1
\$\begingroup\$

Haskell, 67 64 bytes

The input is flipped: 0 means remove right, and 1 remove left:

f n=zipWith(\x y->(' '<$[1..y])++('#'<$[1..n-x]))[0..].scanl(+)0

Try it online!

"Ungolfed"

f n = zipWith (\x y-> replicate y ' ' ++ replicate (n-x) '#') [0..] . scanl (+) 0
\$\endgroup\$
1
\$\begingroup\$

Java (OpenJDK 8), 138 133 bytes

a->n->{char[]s=new char[n];int i=n,v,k[]={0,--n};for(;i-->0;s[i]=35);for(;i++<n;s[k[v=a[i%n]]]=32,k[v]-=v-1|v)System.out.println(s);}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 64 bytes

Anonymous function taking parameters in currying syntax (a)(b). In the b array an empty string represents removing from right and a space represents removing from left.

a=>b=>b.reduce((t,v)=>t+'\n'+(a.pop(),p+=v)+a,a=Array(a+1),p='')

Using 1 and 0 like in the examples the score is 70

a=>b=>b.reduce((t,v)=>t+'\n'+(a.pop(),v?p:p+=' ')+a,a=Array(a+1),p='')

Test

F=
a=>b=>b.reduce((t,v)=>t+'\n'+(a.pop(),p+=v)+a,a=Array(a+1),p='')

function update() {
  var b=B.value.match(/\d/g)
  
  if (b) {
    b=b.map(v=>+v?'':' ')
    O.textContent = F(b.length+1)(b)
  }
  else
    O.textContent = 'invalid input'
}

update()
  
Input B (0 and 1) <input id=B value='1001' oninput='update()'>
<pre id=O></pre>

\$\endgroup\$
1
\$\begingroup\$

Scala, 41 39 bytes

n=>_.scanLeft("#"*n)(" "+_.init drop _)

Try it online!

Uses 1 for dropping a hash on the right, 0 for dropping a hash on the left. Accepts (n)(list). Outputs a list of strings.

Input and output reversed, 35 bytes

n=>_.scanRight("#"*n)(" "*_+_.init)

Try it online!

Help! The sky's falling down!

     #
     ##
    ###
   ####
   #####
  ######
  #######
 ########
#########
##########
\$\endgroup\$
1
\$\begingroup\$

Vyxal, 10 bytes

×*…?(Ṫn$꘍…

Try it Online!

How?

×*…?(Ṫn$꘍…
×*          # Repeat an asterisk the first (implicit) input amount of times
  …         # Print without popping
   ?(       # Loop through the second input
     Ṫ      # Remove the last character of the current string
      n$꘍   # Prepend the current item amount of spaces
         …  # Print without popping
\$\endgroup\$
0
\$\begingroup\$

PowerShell, 53 bytes

param($a,$b)"#"*$a;0..$a|%{" "*($i+=$b[$_])+"#"*--$a}

Try it online!

Takes input $a as the optional integer and $b as the array of 1 and 0s. (Note that my array of 1 and 0 is flip-flopped from the challenge's.) Constructs the initial line of # and leaves that on the pipeline. Then loops from 0 to $a. Each iteration, we output a possibly-incremented number of spaces, followed by a pre-decremented number of #. Yes, this will spit out a blank trailing newline at the end, since we're looping up to $a rather than the number of items in the list.

All the individual strings are left on the pipeline and output with a newline separator between them is implicit at program completion.

\$\endgroup\$
0
\$\begingroup\$

C#, 181 bytes

n=>a=>{var r=new string[n];r[0]=new string('#',n);for(int i=1,p;i<n;++i){r[i]=r[i-1];p=a[i-1]?r[i].LastIndexOf('#'):r[i].IndexOf('#');r[i]=r[i].Remove(p,1).Insert(p," ");}return r;}

Try it online!

Full/Formatted Version:

class P
{
    static void Main()
    {
        System.Func<int, System.Func<bool[], string[]>> f = n => a =>
        {
            var r=new string[n];
            r[0]=new string('#',n);

            for (int i = 1, p; i < n; ++i)
            {
                r[i] = r[i - 1];
                p = a[i - 1] ? r[i].LastIndexOf('#') : r[i].IndexOf('#');
                r[i] = r[i].Remove(p, 1).Insert(p, " ");
            }

            return r;
        };

        System.Console.WriteLine(string.Join("\n", f(5)(new[] { true, false, false, true })));

        System.Console.ReadLine();
    }
}
\$\endgroup\$
0
\$\begingroup\$

Charcoal, 17 bytes

FN«P×#⁺¹ι¿I§⮌ηι↑↖

Try it online! Link is to nearest verbose version of code. Explanation:

FN«

The first input gives the number of loop iterations.

P×#⁺¹ι

Since loop indices default to zero-indexed, we add one here to get the correct number of #s.

¿I§⮌ηι

Starting from the bottom of the tornado and working up saves a byte, but we then need to reverse the second input so that we can index the current digit.

If the current digit is a 1, move up. This makes the previous row have an extra # at the end.

If the current digit is a 0, move up and left. This makes the previous row have an extra # at the start.

\$\endgroup\$
0
\$\begingroup\$

C#, 159 bytes

using System.Linq;n=>a=>new[]{new string('#',n)}.Concat(a.Select((_,i)=>{var s=a.Take(i+1).Count(j=>j==0);var h=n-i-1;return new string('#',h).PadLeft(s+h);}))

Explanation

 new[] { new string('#', n) }                //start with n number of hashes
                .Concat(                     //append...
                    a.Select((_, i) =>       //    map each element of array
                    {
                        var s = a.Take(i + 1).Count(j => j == 0);  // count the number of 0's up to, and including, this point
                        var h = n - i - 1;                         // number of hashes for this step
                        return new string('#', h).PadLeft(s + h);  // number of hashes padded left with number of 0s
                    }));

Try it online!

\$\endgroup\$
0
\$\begingroup\$

PHP, 136 bytes

$b=explode(',',end($argv));$a=$argc==3?$argv[1]:count($b)+1;$c=0;for(;$a;--$a){printf("% {$c}s%'#{$a}s\n",'','');$c+=!array_shift($b);}

Save in a php file and test with php file.php 8 '1,0,0,0,1,0,0'. Output:

########
#######
 ######
  #####
   ####
   ###
    ##
     #

Alas, getting the input ready is half of the job.

Another version (158 bytes) using str_repeat instead of printf and...goto of all things:

$b=explode(',',end($argv));$a=$argc==3?$argv[1]:count($b)+1;$c=0;z:
echo str_repeat(' ',$c).str_repeat('#',$a)."\n";while(--$a){$c+=!array_shift($b);goto z;}
\$\endgroup\$
0
\$\begingroup\$

Jelly, 11 bytes

ŻµJṚżÄUØṖxⱮ

Try it online!

Uses 0 for 1 and 1 for 0, and outputs a list of rows with ! for #. (Note the convenience testing footer ¬ÇY$€Y: negate, join each output on newlines, join the outputs on newlines.)

Żµ             Consider the input with 0 prepended.
    ż          Zip
  J            [1 .. length]
   Ṛ           reversed
     Ä         with the cumulative sums,
      U        and reverse each pair.
          Ɱ    For each pair,
         x     vectorizing repeat
       ØṖ      printable ASCII.

Since dyadic zipwith-vectorization pads with 0 when the shapes of the arguments don't match, every character in the list of printable ASCII characters is repeated 0 times except for space and !.

\$\endgroup\$
0
\$\begingroup\$

APL (Dyalog Unicode), 18 bytes

Takes 1's and 0's swapped.

(0,-+\⎕)⌽⊖↑,\⎕/'#'

Try it online!

⎕/'#' create a string of length n.
,\ get all prefixes of the string.
⊖↑ arrange the prefixes in a character matrix with the longest one at the top.
+\⎕ cumulative sums of the input list.
0,- take the negative of every value and prepend a 0.
rotate each row of the character matrix by a corresponding number of characters.

I think there might be a way to get a list of all column heights and use this to get the output with ⍉↑'#'/⍨¨, but I couldn't figure it out.

\$\endgroup\$
0
\$\begingroup\$

Stax, 9 bytes

éPQ─\▐┐·è

Run and debug it

takes 0 as -1 and 1 as 0.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.