[Question]
  [
As part of a city planning project, you've gotten the assignment of creating a program or function that will display the city skyline, given some input from the architects. The project is only in the startup phase, so a very rough sketch is sufficient. The easiest approach is of course to simply draw the skyline in ASCII-art. 
All buildings will be by the river, thus they are all aligned. The architects will give the height of each building as input, and your code should display the skyline. 
The input from the architects will either be an integer or a half-integer. If the number is an integer, the building will have a flat roof, while a half-integer will result in a pitched roof. A zero will just be flat ground. The walls of a building are 3 characters apart, while a zero will be a single character wide. Adjacent buildings share walls. 
For details and clarifications regarding the output, please have a look at the examples below:
```
N = 3
 ___
|   |
|   |
|___|
N = 3.5
  _      
 / \
|   |
|   |
|___|
N = 6
 ___
|   |
|   |
|   |
|   |
|   |
|___|
n = 0
_
```
Example input: `3 3.5 0 2`
```
      _
 ___ / \  
|   |   |  ___
|   |   | |   |
|___|___|_|___|
```
Example input: `0 0 2.5 3 0 4 1`
```
             ___
    _  ___  |   |
   / \|   | |   |
  |   |   | |   |___
__|___|___|_|___|___|
```
[Louisville](https://i.stack.imgur.com/eePKt.jpg), `0 2 1 3.5 0 4 2 4 2 4 6 1 6 0 5 1`
```
                                    ___     ___
                                   |   |   |   |  ___
           _    ___     ___     ___|   |   |   | |   |
          / \  |   |   |   |   |   |   |   |   | |   |
  ___    |   | |   |___|   |___|   |   |   |   | |   |
 |   |___|   | |   |   |   |   |   |   |___|   | |   |___
_|___|___|___|_|___|___|___|___|___|___|___|___|_|___|___|
```
The ASCII-characters used are: newline, space, and `/\_|` (code points 10, 32, 47, 92, 95, 124).
**Rules:**
* It's optional to make a program that only take integers as input, by multiplying all numbers by two. So, instead of taking `3 3.5 2`, your program may take `6 7 4`. If the second input format is chosen, an input of 6 should result in a 3 story building, 7 should be a 3 story building with pitched roofs etc.
* The output should be exactly as described above, but trailing spaces and newlines are OK.
* The exact format of the input is optional. Whatever is best in your language.
* The result must be displayed on the screen, so that the architects can have a look at it.
* You can assume there will be at least one integer given, and that only valid input will be given.
**This is codegolf, so the shortest code in bytes win.**
  
[Answer]
# Python 2, ~~199~~ ~~193~~ ~~188~~ 185 bytes
```
a=map(int,raw_input().split())
l=max(a)+1|1
while~l:print''.join((x%2*'/  _\\ '[x<l::2]*(x<=l<x+4)or'_ '[x|1!=l>1]*3)[x<1:x+2]+'| '[x<=l>=y]*(x+y>0)for x,y in zip([0]+a,a+[0]))[1:];l-=2
```
This is a full program that accepts integers as input. [Example input](http://ideone.com/M2uYzL).
[Answer]
# MATLAB, ~~219 209~~ 203 bytes
```
i=input('');x=1;c=0;m(1:4*numel(i))='_';for a=i;b=fix(a);m(1:b,x)='|';s=95;if a~=b;m(b+2,x+2)=95;s='/ \';end;m(b+1,x+(1:3))=s;x=x+(a>0)*3+1;m(1:b,x)='|';x=x+(a<1&c>0);c=a;end;disp(flipud(m(:,1:x-(a<1))))
```
This unfortunately doesn't work on **Octave**. Not entirely sure why, seems to be something to do with the disp/flipud bit that breaks.
Also, there is currently no definition of what a 0.5 height building looks like, nor any mention of them, so in this code I assume that they are disallowed.
The following is the code in a slightly more readable way:
```
i=input(''); %e.g. [0 0 2 1 3.5 0 4 2 4 2 4 6 1 6 0 5 1 0 0 1 0]
x=1;
c=0;
m(1:4*numel(i))='_';
for a=i;
    b=fix(a);
    m(1:b,x)='|';
    s=95;
    if a~=b;
        m(b+2,x+2)=95;
        s='/ \';
    end;
    m(b+1,x+(1:3))=s;
    x=x+(a>0)*3+1;
    m(1:b,x)='|';
    x=x+(a<1&c>0);
    c=a;
end;
disp(flipud(m(:,1:x-(a<1))))
```
---
First we take an input as an array, and do some variable initialisation.
```
i=input(''); %e.g. [0 0 2 1 3.5 0 4 2 4 2 4 6 1 6 0 5 1]
x=1;
c=0;
```
Because the zero height buildings are a pain - they basically end up with a width which is dependent on what they are next to (though what is printed doesn't change), we simplify things by drawing enough ground for all of the buildings. We assume each building will be 4 characters wide (because adjacent buildings merge together) - zero height ones aren't, but the excess will be trimmed later.
```
m(1:4*numel(i))='_';
```
Now we draw out each building in turn.
```
for a=i
```
First we get the integer part of the height as this will determine how many '|' we need.
```
    b=fix(a);
```
Now draw in the wall for this building - if there are two adjacent buildings, the wall for this new one will be in the same column as the wall from the last one.
```
    m(1:b,x)='|';
```
Check to see if this is a half height building. If it is, then the roof will be different. For the half heights, the roof is going to be `/ \` whereas full height ones it will be `___` (Matlab will implicitly replicate this from a single underscore, so save a couple of bytes there). There is an extra bit of roof one row higher for the half height buildings, so that is added as well.
```
    s=95;
    if a~=b;
        m(b+2,x+2)=95;
        s='/ \';
    end;
```
Draw in the roof
```
    m(b+1,x+(1:3))=s;
```
Now move to the start of the next building and draw in the shared wall (if the wall is too short at this point, it will be made larger when the next building is drawn). Note that zero height buildings are 1 wide, normal buildings are 4 wide, so we simplify what would otherwise be an if-else by treating (a>0) as a decimal number not a Boolean.
```
    x=x+(a>0)*3+1;
    m(1:b,x)='|';
```
Next comes a bit of hackery to work with zero height buildings. Basically what this says is if this building was zero height, and the one before that wasn't, it means the place of the next building needs incrementing by 1 because a zero height building sandwiched between two other buildings is effectively twice as wide - this accounts for the extra wall which is normally shared with an adjacent building. We also keep track of this building height for doing this check next time.
```
    x=x+(a<1&c>0);
    c=a;
end;
```
Once done, flip the building matrix to be the correct way up, and display it. Note that we also trim off any excess ground here as well.
```
disp(flipud(m(:,1:x-(a<1))))
```
---
So, when we run this script, we are asked for our input, for example:
```
[0 0 2 1 3.5 0 4 2 4 2 4 6 1 6 0 5 1 0 0 1 0]
```
It then generates the building and displays the result. For the above input, the following is generated:
```
                                     ___     ___                   
                                    |   |   |   |  ___             
            _    ___     ___     ___|   |   |   | |   |            
           / \  |   |   |   |   |   |   |   |   | |   |            
   ___    |   | |   |___|   |___|   |   |   |   | |   |            
  |   |___|   | |   |   |   |   |   |   |___|   | |   |___    ___  
__|___|___|___|_|___|___|___|___|___|___|___|___|_|___|___|__|___|_
```
[Answer]
## Kotlin, ~~447~~ 442 bytes
```
val a={s:String->val f=s.split(" ").map{it.toFloat()}.toFloatArray();val m=(f.max()!!+1).toInt();for(d in m downTo 0){var l=0f;for(c in f){val h=c.toInt();print(if(h==d&&d!=0)if(h<l-0.5)"|" else{" "}+if(c>h)"/ \\" else "___" else if(h<d)if(d<l-0.5)"|" else{" "}+if(h==0)" " else if((c+0.5).toInt()==d)" _ " else "   " else{if(h==0)if(l<1)"  " else "| " else "|   "}.replace(' ',if(d==0)'_' else ' '));l=c;};if(d<l-0.5)print("|");println();}}
```
## Ungolfed version:
```
val ungolfed: (String) -> Unit = {
    s ->
    val floats = s.split(" ").map { it.toFloat() }.toFloatArray()
    val maxH = (floats.max()!! + 1).toInt()
    for (drawHeight in maxH downTo 0) {
        var lastBuildingH = 0f
        for (f in floats) {
            val buildingH = f.toInt()
            if (drawHeight == 0) {
                // Baseline
                if (buildingH == 0)
                    if (lastBuildingH.toInt() == 0) print("__")
                    else print("|_")
                else print("|___")
            } else if (buildingH == drawHeight) {
                // Ceiling
                if (buildingH < lastBuildingH - 0.5) print("|")
                else print(" ")
                if (f > buildingH) print("/ \\")
                else print("___")
            } else if (buildingH < drawHeight) {
                // Above building
                if (drawHeight < lastBuildingH - 0.5) print("|")
                else print(" ")
                if (buildingH == 0) print(" ")
                else {
                    if ((f + 0.5).toInt() == drawHeight) print(" _ ")
                    else print("   ")
                }
            } else {
                if (buildingH == 0) print("| ")
                else print("|   ")
            }
            lastBuildingH = f;
        }
        if (drawHeight < lastBuildingH - 0.5) print("|")
        println()
    }
}
```
[Answer]
## Python 2, ~~357~~ ~~306~~ ~~299~~ ~~294~~ ~~287~~ ~~281~~ 276 bytes
```
def s(l):
 d=len(l)+1;l=[0]+l+[0];h=(max(l)+3)/2;o=''
 for i in range(d*h):
  a=l[i%d+1];c=l[i%d];b=2*(h-1-i/d);o+="|"if(a>b+1)+(c>b+1)else" "*(a+c>0);o+=" _/__  _\\"[a-b+1::3]if b*(1>=abs(a-b))else" "*(1+2*(a>0))
  if b==0:o=o.replace(" ","_")
  if i%d==d-1:print o[:-1];o=''
```
This uses the "doubled" encoding, to be passed to the function as a list.
Edit: Shaved bytes by redoing part of the big conditional as an array selector, and switching to the doubled encoding. Shaved more bytes by rearranging the conditional even more and converting more logic to arithmetic.
EDIT: [xsot's is better](https://codegolf.stackexchange.com/a/65293/47050)
### Explanation:
```
d=len(l)+1;l=[0]+l+[0];m=max(l);h=m/2+m%2+1;o=''
```
`d` is 1 more than the length of the array, because we're going to add zeros on each end of the list from the second element up to the zero we added on the end. `h` is the height of the drawing. (We have to divide by 2 in this calculation because we are using the doubled representation, which we use specifically to avoid having to cast floats to ints all over the place. We also add 1 before dividing so odd heights--pointy buildings--get a little more clearance than the regular kind.) `o` is the output string.
```
 for i in range(d*h):
```
A standard trick for collapsing a double for loop into a single for loop. Once we do:
```
  a=l[i%d+1];c=l[i%d];b=2*(h-1-i/d)
```
we have now accomplished the same as:
```
for b in range(2*h-2,-2,-2):
 for j in range(d):
  a=l[j+1];c=l[j]
```
but in a way which nets us ten bytes saved (including whitespace on the following lines).
```
  o+="|"if(a>b+1)+(c>b+1)else" "*(a+c>0)
```
Stick a wall in any time the height of either the current building or the previous building is taller than the current line, as long as there is at least one building boundary here. It's the equivalent of the following conditional:
```
  o+=("|" if a>b+1 or c>b+1 else " ") if a or c else ""
```
where b is the current scan height, a is the current building height, and c is the previous building height. The latter part of the conditional prevents putting walls between ground spaces.
```
  o+=" _/__  _\\"[a-b+1::3]if b*(1>=abs(a-b))else" "*(1+2*(a>0))
```
This is the part that draws the correct roof, selecting roof parts by comparing the building's height with the current scan height. If a roof doesn't go here, it prints an appropriate number of spaces (3 when it's an actual building, e.g., a>0, otherwise 1). Note that when we're at ground level, it never attempts to draw a roof, which means 0.5 size buildings don't get pointy roofs. Oh well.
```
  if b==0:o=o.replace(" ","_")
```
When we're at ground level, we want underscores instead of spaces. We just replace them all in at once here.
```
  if i%d==d-1:print o[:-1];o=''
```
Just before we start processing the next line, print the current one and clear the output line. We chop off the last character because it is the "\_" corresponding to the ground space we added by appending a zero at the beginning of the function. (We appended that zero so we would not have to add a special case to insert a right wall, if it exists, which would add far more code than we added by adding the 0 and chopping off the "\_".)
[Answer]
# Python 3
## ~~725 bytes~~
## 608 bytes
Golfed code:
```
import sys,math;
m,l,w,s,bh,ls,ins,r,a="|   |","___","|"," ",0,[],[],range,sys.argv[1:]
def ru(n):return math.ceil(n)
def bl(h,n):
    if(n>ru(h)):return(s*5,s)[h==0]
    if(h==0):return"_"
    if(n==0):return w+l+w
    if(n<h-1):return m
    return("  _  "," / \ ")[n==ru(h)-1]if(h%1)else(s+l+s,m)[n==h-1]
for arg in a:
    f=ru(float(arg))
    if(bh<f):bh=f
for i in r(bh,-1,-1):
    ln=""
    for bld in a:ln+=bl(float(bld),i)
    ls.append(ln)
for i in r(len(ls[-1])-1):
    if(ls[-1][i]==ls[-1][i+1]==w):ins.append(i-len(ins))
for ln in ls:
    for i in ins:ln=(ln[:i]+ln[i+1:],ln[:i+1]+ln[i+2:])[ln[i]==w]
    print(ln)
```
Here's the ungolfed code. There are some comments but the basic idea is to create buildings with double walls, so the bottom line looks like:
```
_|___||___|_|___||___|
```
Then to get indexes of those double walls and remove those columns so we get:
```
_|___|___|_|___|___|
```
Code:
```
import sys
import numbers
import math
mid="|   |";
l="___";
w="|";
s=" ";
def printList(lst):
    for it in lst:
        print(it);
# h = height of building
# l = line numeber starting at 0
def buildingline(h,n):
    #if (h==0):
    #   return " " if(n>math.ceil(h)) else "   ";
    if(n>math.ceil(h)):
        return s if(h == 0) else s*5;
    if(h==0): return "_";
    if(n==0): return w+l+w;
    if(n<h-1): return mid;
    if(h.is_integer()):
        return mid if(n==h-1) else  s+l+s;
    else:
        return " / \ " if (n==math.ceil(h)-1) else "  _  "; 
# max height
bh=0;
for arg in sys.argv[1:]:
    f = math.ceil(float(arg));
    if(bh<f):bh=f;
# lines for printing
lines = []
for i in range(bh,-1,-1):
    line="";
    for bld in sys.argv[1:]:
        bld=float(bld);
        line += buildingline(bld,i);
        #lh = bld;
    lines.append(line);
    
#for line in lines:
#   print(line);
#printList(lines);
    
    
# column merging
#find indexes for merging (if there are | | next to each other)
indexes = [];
for i in range(len(lines[-1])-1):
    if (lines[-1][i]=='|' and lines[-1][i+1] == '|'):
        indexes.append(i-len(indexes));
        
#printList(indexes);
#index counter
for line in lines:
    newLine = line;
    for i in indexes:
        if newLine[i] == '|' :
            newLine=newLine[:i+1] + newLine[i+2:];
        else : newLine = newLine[:i] + newLine[i+1:];
    print(newLine);
```
Time to do some golfing!
[Answer]
## PHP, ~~307~~ ~~297~~ 293 bytes
```
<?$r=str_pad("",$p=((max($argv)+1)>>1)*$w=4*$argc,str_pad("\n",$w," ",0));for(;++$i<$argc&&$r[$p++]=_;$m=$n)if($n=$argv[$i]){$q=$p+=!$m;eval($x='$r[$q-1]=$r[$q]=$r[$q+1]=_;');for($h=$n>>1;$h--;$q-=$w)$r[$q-2]=$r[$q+2]="|";$n&1?($r[$q-1]="/")&($r[$q-$w]=_)&$r[$q+1]="\\":eval($x);$p+=3;}echo$r;
```
Takes arguments\*2 from command line. save to file, run with `php <filename> <parameters>`.
**breakdown**
```
// initialize result    
$r=str_pad("",              // nested str_pad is 3 bytes shorter than a loop
    $p=                     // cursor=(max height-1)*(max width)=(start of last line)
    ((max($argv)+1)>>1)     // max height-1
    *
    $w=4*$argc              // we need at least 4*($argc-1)-1, +1 for newline
    ,
    // one line
    str_pad("\n",$w," ",0)  // (`str_pad("",$w-1)."\n"` is one byte shorter,
);                          // but requires `$w+1`)
// draw skyline
for(;
    ++$i<$argc              // loop through arguments
    &&$r[$p++]=_                // 0. draw empty ground and go one forward
    ;
    $m=$n                       // 7. remember value
)
    if($n=$argv[$i])            // if there is a house
    {
        $q=                         // 2. copy $p to $q
        $p+=!$m;                    // 1. go one forward if there was no house before this
        // offset all further positions by -2 (overwrite empty ground, share walls)
        eval($x=                    // 3. draw floor
        '$r[$q-1]=$r[$q]=$r[$q+1]=_;'
        );
        for($h=$n>>1;$h--;$q-=$w)   // 4. draw walls
            $r[$q-2]=$r[$q+2]="|";
        $n&1                        // 5. draw roof
            ?($r[$q-1]="/")&($r[$q-$w]=_)&$r[$q+1]="\\"
            :eval($x)               // (eval saved 7 bytes)
        ;                           // (ternary saved 6 bytes over `if`)
        $p+=3;                      // 6. go three forward (5-2)
    }
// output
echo$r;
```
[Answer]
# C++, ungolfed
(or maybe ungolfable)
Assuming there are less than 100 elements and each element is less than 100. `s` is the number of buildings (required in input).
```
#include <iostream>
using namespace std;
int main()
{
float a[100];
int i,j,s;
cin>>s;
for(i=0;i<s;++i)
 cin>>a[i];
for(i=100;i>=1;--i)
{
for(j=0;j<s;++j)
{
if((a[j]>=i)||(a[j-1]>=i))
 cout<<"|";
else
 cout<<" ";
if(i==1)
 cout<<"___";
else if(a[j]+1==i)
 cout<<"___";
else if(a[j]+1.5==i)
 cout<<" _ ";
else if(a[j]+0.5==i)
 cout<<"/ \\";
else cout<<"   ";
}
if(a[s-1]>=i)
 cout<<"|";
cout<<endl;
}
}
```
]