# Construct a Tornado

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]

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

100,
[1,0,0,0,0,1,0,0,0,1,1,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,1,1,0,1,0,1,1,0,0,1,0,1,1,0,0,1,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,1,0,1,0,0,1,1,0,0,0,0,1]


Long test case

# 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

• 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? – Charlie Jul 20 '17 at 20:02
• @CarlosAlejo No... That doesn't make sense then because then you won't have enough elements to remove at the end... – HyperNeutrino Jul 20 '17 at 20:15
• The glasses that @HyperNeutrino used to see his first tornado: i.imgur.com/TzMm94a.png – Magic Octopus Urn Jul 21 '17 at 2:04
• @MagicOctopusUrn...lol – HyperNeutrino Jul 21 '17 at 2:11

# V, 15, 12 bytes

ïÀé#òÙxHxG@"


Try it online!

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

# 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

• ninja'd me :((( – Koishore Roy Jul 20 '17 at 19:58
• Same here man :/ – Arnold Palmer Jul 20 '17 at 19:59
• 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". – Arnold Palmer Jul 20 '17 at 20:03

# 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. • Can you not use ^ instead of ␛OH? – Neil Jul 21 '17 at 9:19 • @Neil ^ goes to the first non-blank character. ␛OH goes to the first character. – Ray Jul 24 '17 at 21:28 • Ah, sorry, I meant 0 didn't I... – Neil Jul 24 '17 at 21:30 • @Neil In that case, yes, I should be doing that. Thanks. – Ray Jul 24 '17 at 21:40 # 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  • 0×ηsηO has so much potential but I can't figure it out under 11 bytes. – Magic Octopus Urn Jul 21 '17 at 1:58 • Keep the latter version and replace ðy×ì with yú for -2. – Erik the Outgolfer Jul 21 '17 at 8:38 # Retina, 30 28 bytes .?$#$&$'¶
Td##.*
Td _


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

# J, 32 bytes

' #'#~[:(],.1+i.@-@#)0,(+/\@:-.)


### ungolfed

' #'#~ [: ( ] ,. 1+i.@-@# )  0 , (+/\ @: -.)


Try it online!

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

## Perl, 43 bytes

42 bytes code + 1 for -l.

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


Try it online!

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

• I knew making a matrix wasn't the best option! – Giuseppe Jul 21 '17 at 13:21
• 82 bytes -- shaved off the {} and used a literal newline instead of '\n' – Giuseppe Jul 21 '17 at 13:23

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


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

• I think you can do s=" "*i+s[:-1] with left and right swapped. – xnor Jul 20 '17 at 21:38

# R, 116109 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.

• 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 – user2390246 Jul 21 '17 at 13:08
• @user2390246 very nice! I managed to shave off another pair of bytes as well :) – Giuseppe Jul 21 '17 at 13:20

# 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-- (V´) times. This also decrements V each time.

• Good one. I think you can save a byte by changing YnV to V´ – ETHproductions Jul 21 '17 at 20:52
• @ETHproductions Awesome, thanks! I totally forgot about using ++ or -- in Japt. – Justin Mariner Jul 21 '17 at 21:01

# 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

• 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! – HyperNeutrino Jul 21 '17 at 21:30
• @HyperNeutrino Fair enough, this is as good as you can get from ArnoldC. – TemporalWolf Jul 21 '17 at 21:32
• 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 :) – HyperNeutrino Jul 21 '17 at 21:41
• @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. – TemporalWolf Jul 21 '17 at 21:57
• You're right. Fair enough, carry on; I misjudged. Nice answer :) – HyperNeutrino Jul 21 '17 at 22:05

# 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


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

# C, 68 63 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[]){1, 0, 0, 0, 1, 0, 0});
}

• Save 5 bytes by removing int s=0; and putting s; before the f(w,i). Like so – MD XF Jul 21 '17 at 22:10

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

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

# 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();
}
}


# Charcoal, 17 bytes

ＦＮ«Ｐ×#⁺¹ι¿Ｉ§⮌ηι↑↖


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

ＦＮ«


The first input gives the number of loop iterations.

Ｐ×#⁺¹ι


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

¿Ｉ§⮌ηι


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.

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

## 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;}