text:
42 in Rod Logic
Write the shortest possible program which takes a numeric input and outputs the result of adding 42 to the input.
f(x) -> x + 42

There's only one restriction. Your program can only be composed of rod logic characters...

The definition for a rod logic character is a one that is composed purely of straight lines. They come from the crazy Temporally Quaquaversal Virtual Nanomachines talk by Damian Conway. To simplify things The following will be considered the set of all valid rod logic characters.
_ | - = \ / < > [ ] ^ +
Damian writes a rod logic program in Perl which takes a numeric input and outputs the result of adding 42 in 170 lines. He might be great at quantum mechanics in Perl, but I'm not sure he's played much code golf. The challenge is to improve on that.
Like Damian's example we'll say that you have access to two predefined functions:

__ - which prints arguments
___ - which reads and returns user input

If these aren't valid function identifiers in your language, you can replace them with other (2 and 3 byte ones)
Shortest program wins.

Do rod characters prohibit crossing lines? For example '4' or 'x'? What about serifs in things like '1'?

@orlp maybe not, but alphanumeric characters are forbidden anyway

No way to do this in C like languages (C, C++, Java, Javascript) as calling a function require () and these have curves

Crossing lines is fine! Serifs aren't. Alphanumerics are gone to try and make that murky territory a bit easier.

@MartinBüttner Sure, good shout.

@DanPrince I'm sorry, this golf question got a downvote from me, it seems to be too arbitrary to be fun to me.

Would a function be alright in Java?

Whether or not a character is permitted seems to depend on the font one uses, so I'm voting to close as unclear until an exhaustive list of permitted characters is included.

@PeterTaylor that's fair enough. Updated the question to provide one.

Brainfuck, 25
,>++++++[<+++++++>-]<.

Counting , as ___ (input) and . as __ (output).
Works by adding 7 to the input 6 times.

CJam, 22 21 bytes
CJam only supports single-character function (block) names, all of which must be uppercase letters. I've used A in place of ___ and counted it as 3 bytes:
]_=__+__+++__++_+A+

Test it here.
Explanation
]_=                  "Make an empty array, duplicate, check for equality, pushing 1.";
   __+               "Get two copies and add them, leaving the stack as [1 2].";
      __+++          "Make two copies add it all up, yielding 7.";
           __++      "Make two copies, add them up, yielding 21.";
               _+    "Make a copy add it, yielding 42.";
                 A+  "Read the input and add it.";

CJam automatically prints the stack contents at the end of the program.

JavaScript, 64+3+2=69
+[+[++[++[++[+[]==[]][+[]]][+[]]][+[]]+[++[+[]==[]][+[]]]]][+[]]

To test it, write a number followed by the whole program in your browser's console.
I didn't explicitly use input and output functions, but I added 3 and 2 bytes to account for them.
Explanation:
+[] ➜ 0
0==[] ➜ true
++[true][0] ➜ 2
++[2][0] ➜ 3
++[3][0] ➜ 4
4+[2] ➜ "42"
+["42"] ➜ 42
x+[42][0] ➜ x+42

I tried beautifying the code to step through it but I gave up after a little. Props to extreme type coercion.

@rink.attendant.6 thanks, updated now

I eventually figured it out though I was a bit surprised that 4+[2] evaluates to "42".

+[]==[] => []<=[]?

Pyth, 54 + 3 bytes = 57
+vz-+^/+\\\\\\/+++\\\\\\\\\\^/++\\\\\\\\/++\\\\\\\\/\\\\

Just to show that it can be done in Pyth. ___ isn't valid in Pyth, so I'm using vz.
/ is the only command which returns a number, when used as / <string1> <string2> to mean string1.count(string2), so we use it excessively to create numbers. The 42 is calculated as 2^4 + 3^3 - 1.
Try it online.

I don't know Pyth but if you use a letter like L, T, E, etc. it would be more fitting with the straight lines concept.

@rink.attendant.6 Q is evaluated input in Pyth, which is why I chose it. vz works just as well, so I've changed it to that.

JavaScript / TypeScript / CoffeeScript, 38 bytes
_ is a valid identifier in JS.
The question is somewhat unclear but I'm assuming that ___ stores input and __ stores output.
The newlines are necessary (and counted as 1 byte each) regardless of whether you're running it as JavaScript (for ASI) or CoffeeScript (for compilation to JS).
_=[]
___+=++_<<++_<<++_
__=___+_+_+++_

Explanation
# assigns empty array to _ which will be coerced to number 0 later
_=[]

# Add 32 to input:
#   0+1 << (0+1)+1 << ((0+1)+1)+1 = 1 << 2 << 3
#    = 1 << 2 << 3
#    = 4 << 3
#    = 32 or 0b00100000
# (Also note that _ = 3 now)
___+=++_<<++_<<++_

# Previous value + 3 + 3 + 4
# Total additions: 32 + 3 + 3 + 4 = 42
__=___+_+_+++_

Demo
This is the best I can try to demonstrate it:

function ____(___) {
  _ = []
  ___ += ++_ << ++_ << ++_
  __ = ___ + _ + _ + ++_
  return __
}

document.getElementById('btn').addEventListener('click', function() {
  window.alert(____(+document.getElementById('foo').value));
  return false;
});
<label>
  Enter a number:
  <input type=number id=foo value=0>
</label>
<button type=button id=btn>Add 42</button>

piet - 14
This might count. All of the lines are straight.

The question explicitly whitelists the allowed characters. Your program doesn't use those.

C++
This is a work in progress... how can I replace () with []? Is it possible?
#include <iostream>
using namespace std;

#define _____(a) int main(){a return 0;}
#define ___(y) cin>>y;
#define __(x) cout<<x<<endl;
#define ______(z) z+=42;
#define ________(p) int p;

_____(________(_) ___(_) ______(_) __(_) ___(_))

alphanumerics are out, so no #defines I'm afraid. I don't think this is possible in C++.

This program exhibits undefined behavior and is as such not repeatable.


text:
Encoding an URL in brainfuck
Inspired by this question, your goal today is to encode an URL in brainfuck.
My browser has been hacked! The location bar has been turned into a brainfuck interpreter. I need a program that turns an URL into a brainfuck program. My computer is also very slow, so if the brainfuck program is small it's better.
Oh and I only have one working tab left open, my twitter. So you can only send me the program in a tweet.

Write a program that fits in a tweet (140 characters) in any language that takes a string as input and outputs a brainfuck program.
This brainfuck program will be run without input and will generate an output.
This output will be inserted into the location bar of Google Chrome, and executed.
If the behaviour of Google Chrome is identical to the behaviour you would get by entering the input string from #1, then the solution is valid. Redirection by URL shorteners is considered different behaviour - stay at least on the same domain.

You may assume the brainfuck interpreter has infinite precision signed integers in each cell and an unlimited amount of cells.
Your score is determined by the sum of the lengths of the brainfuck programs generated to encode the following set of URLs:
https://www.google.com/
https://codegolf.stackexchange.com/questions/47895/
http://www.golfscript.com/golfscript/examples.html
http://en.wikipedia.org/wiki/Percent-encoding
ftp://ftp.freebsd.org/pub/FreeBSD/
https://github.com/isaacg1/pyth/blob/master/doc.txt#L92
http://ftp.gnu.org/non-gnu/nethack/nethack-3.4.0.tar.gz.back-RSN.README

Smallest score wins.

May we assume that the input would be formatted like this: http://www.google.com/ or will it ever simply be google.com? (Both are valid as far as Google Chrome is concerned, but your list only contains the full forms) P.S. I almost have a desire to write an extension for chrome that does this...

@BrainSteel The input for your encoder will be exactly as stated as in the question (each line is one input). The output of the brainfuck may be any format accepted by Google Chrome, as long as it has the same behaviour as the original input string. So if your program takes input http://www.google.com/ the brainfuck program it produces may output google.com, www.google.com, etc, because they all result in the same page. But for example ftp://ftp.freebsd.org/pub/FreeBSD/ is not the same as ftp.freebsd.org/pub/FreeBSD/.

Ah, thank you for clarifying! Sorry, I'm a bit slow this morning.

I would like to clarify that I failed, and that ftp://ftp.freebsd.org/pub/FreeBSD/ is indeed the same as ftp.freebsd.org/pub/FreeBSD/ in Google Chrome. This makes the challenge a bit easier than I intended, but such is life. I won't change the requirements, so it's safe to just strip off anything before ://.

Pyth - 118 bytes, score: 154 + 567 + 597 + 620 + 530 + 875 + 1092 = 6630 6623 4653 4435
Now using the factor multiplication algo!
This is a pretty simple algorithm, although slightly better than the above ones. I was planning to use Pyth, but with the current algorithm Python fits<140 bytes.
=zecz"//"=z?>z4}"www."zz=z?Pzqez\/zFNzKCNJ/^K.5 1=d\+pk+holN[?*-KZd>KZ*-ZK\-+\>*dK+++++\>*Jd"[>"*Jd"<-]>"*-K*JJd)\.=ZK

It first strips out the http:// by using split("//") and the www. and / at the end. Then it uses the min function to check which is the best of the the three options that is considered:

Use + or - to update current cell value to desired cell value
Go to new cell and just fill with +'s
Go to new cell and use multiplication to update by doing sqrt(n)*sqrt(n)+remainder since square has minimum perimeter of constant area. http://cydathria.com/bf/bf_ex3.html

I then always put a . to output each char.
A detailed explanation of the new code is coming soon. I kind of half-assed the golfing, especially the stripping of www. and the / at the end but I can't be bothered since I'm 20 bytes under the limit.
This surprisingly works on the ftp:// urls since this is chrome and chrome automatically makes ftp.freebsd.org/pub/FreeBSD/ into ftp://ftp.freebsd.org/pub/FreeBSD/
I plan to next use a dictionary to store the cell values and see if the character was already made in a cell.

Brainfuck Omnibox Extension
That's right! After I saw @BrainSteel's comment, I knew I had to make it. This doesn't take over the entire omnibox, only when you do bf,tab. Also since the omnibox api is weird, it doesn't let me forward the code to the omnibox, I have to handle it myself. So I do my own http:// checking and then set the tab's url.
Since I didn't feel like paying the $5 necessary to put your extension on the webstore, you guys will have to install it manually. Just download the zip from here: https://drive.google.com/file/d/0B0qkKIzGc0QiNzBzVUJjZkRIZ0k/view?usp=sharing, unzip, go into the extensions page in chrome, click dev mode option box on top-right, and load the unpacked extension.
Hope you guys enjoy! :)

This won't work on the ftp:// URL.

@Pietu1998 that's what I thought at first but Chrome surprised me. Try putting in ftp.freebsd.org/pub/FreeBSD/ in your address bar and Chrome will make it ftp:// ftp.freebsd.org/pub/FreeBSD/

@Maltysen Oops. I had intentionally included that URL to prevent this optimization, but it looks like I failed. This URL is indeed different, but it seems Chrome is indeed smart enough to recognize and add ftp://. Oh well.

C, 140 134 132 138 128 139 Bytes
263 + 816 + 911 + 955 + 827 + 1355 + 1779 = 7269 6906 bytes
Update: 6 bytes less, thanks to nutki!
Update again, 128 bytes. Code is significantly less readable. It now attempts to strip the URL of ftp://, too.
Update the third, at 139 bytes. Code is a bit more readable, and got rid of some nasty undefined behavior. Now, if the site name is preceded by www., it is stripped. I got under 7k, but I think I must concede to Maltysen with Pyth. Well done.
#define p putchar
a;main(int c,char**V){while(*V[1]++-47);*++V+=1;for(*V+=**V-'w'?0:4;c=**V;*V+=1,p(46))for(;c-a;a+=c>a?1:-1)p(c>a?43:45);}

Unraveled a bit:
#define p putchar
a;
main(int c,char**V){
    while(*V[1]++-47);
    *++V+=1;
    for(*V+=**V-'w'?0:4;c=**V;*V+=1,p(46))
        for(;c-a;a+=c>a?1:-1)
            p(c>a?43:45);
}

This code takes a URL at the command line, and converts it into BF using only .,-, and +. The code makes an attempt to strip the string of ftp://,http://,https://, and www. before converting to BF. Here is a list of outputs of the outputs:
google.com/
codegolf.stackexchange.com/questions/47895/
golfscript.com/golfscript/examples.html
en.wikipedia.org/wiki/Percent-encoding
ftp.freebsd.org/pub/FreeBSD/
github.com/isaacg1/pyth/blob/master/doc.txt#L92
ftp.gnu.org/non-gnu/nethack/nethack-3.4.0.tar.gz.back-RSN.README

How about using one inner loop: for(;c-a;a+=c>a,a-=c<a)p(c>a?43:45) should work.

@nutki Impressive! Thank you!

"Note that if we may assume no URL begins with anything other than http://, https://, or ftp://, we can drop 10 bytes from this solution." Your solution only has to work for the dataset above, so you may assume whatever you want, as long as the dataset will still be handled correctly/

@orlp Hooray! That sounds like 12 bytes to play with! Thank you for this challenge, it's been great fun!

Brainfuck, 77 bytes, Score = 31647
Score is the sum of codepoint+4 for every character.
+++++[>+++++++++<-]>+[>++>+>++>+>+<<<<<-]>+>->->>--->,[[<.>-]<<.<.<.<.>>>>>,]

(Uses BF implementation with EOF = 0.)
Example:
input:
!bar

output:
+++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]

JavaScript (ES6) - 137 bytes, score - 7413
This uses only ., + and -. You can test it in Firefox console.
B=s=>[...s.replace(/^h.+\/\//,'')].map((c,i,a)=>(v=i?c[C]()-a[i-1][C]():c[C='charCodeAt']())?'-+'[v>0|0].repeat(v>0?v:-v):'').join('.')+'.'

This is my score counter:

[
    'https://www.google.com/',
    'http://codegolf.stackexchange.com/questions/47895/',
    'http://www.golfscript.com/golfscript/examples.html',
    'http://en.wikipedia.org/wiki/Percent-encoding',
    'ftp://ftp.freebsd.org/pub/FreeBSD/',
    'https://github.com/isaacg1/pyth/blob/master/doc.txt#L92',
    'http://ftp.gnu.org/non-gnu/nethack/nethack-3.4.0.tar.gz.back-RSN.README'
].map(B).join('').length

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
Quiche Lorraine
Since it was Pi day recently, I have noticed a number of challenges that ask you to calculate pi.
Of course, a quiche lorraine is not quite a pie (you can claim a Bonus Score¹ of +1 if you guessed the challenge off of the title). As such, your job is to write an algorithm or method that looks like it approximates Pi at first glance, but is guaranteed not to converge towards Pi.
This is an underhanded challenge, so make sure it will output 3.14... for a simple test case, e.g. with 10 iterations of your algorithm. This is also a popularity challenge, so don't go for the obvious echo(pi) and say that IEEE 754 floating point rounds some digits up or down.
Winner gets a quiche lorraine².
¹ Warning: not actually a bonus score. By claiming the score, you agree to bake me a pie before Pi Day, 2016
² Warning: quiche lorraine is used as a metaphor for having your answer marked as 'accepted'

Related: link

I'm voting to close this question as off-topic because underhanded challenges are no-longer on-topic here. http://meta.codegolf.stackexchange.com/a/8326/20469

Algorithm
Using the well-known result:

we define in Python 3:
from math import sin
from functools import reduce
from operator import mul

def integrate(f, a, b, n):
   h = (b-a)/n
   i = h * sum(f(a+i*h+h/2) for i in range(n))
   return i

def sinc(x):
   return sin(x)/x

def borwein(n):
   def f(x):
     g = lambda i: sinc(x/(2*i+1))
     return reduce(mul, map(g, range(n)), 1)
   return f

Testing
>>> for i in range(1,10):
...   pi = 2 * integrate(borwein(i), 0, 1000, 1000)
...   print("x[{}] = {}".format(i, pi))
x[1] = 3.140418050361841
x[2] = 3.141593078648859
x[3] = 3.1415926534611547
x[4] = 3.1415926535957164
x[5] = 3.1415926535895786
x[6] = 3.1415926535897953
x[7] = 3.1415926535897936
x[8] = 3.1415926535435896 # ???
x[9] = 3.141592616140805  # ?!!

Spoiler

 The Borwein integral is math's idea of a practical joke. While the identity above holds up to sinc(x/13), the next value is actually:

Probably one of the best answer to a underhanded question in recent times.

"math's idea of a practical joke". +1

That's a good one! IIRC, one of the more well-known jokes with this integral was when someone recorded the results up to the weird one on Wolfram Alpha, and sent a bug report... Which the WA devs spent ages trying to fix =)

This reference gives a good explanation of what is going on.

To find pi, we will integrate this well known differential equation:

With an initial condition

It is well known that this initial value problem converges to π as t increases without bound. So, all we need is to start with a reasonable guess for something between 0 and 2π, and we can perform numerical integration. 3 is close to π, so we will pick y = 3 to start.
class PiEstimator {

    static final int numSteps = 100;
    static final double dt = 0.1, tMax = numSteps * dt;

    static double f(double y, double t){ return Math.sin(y) * Math.exp(t); }

    public static void main(String[] args){
        double y = 3;
        int n = 0;

        for(double t = 0; t < tMax; t+=dt){
            if(n%5 == 0) System.out.println(n + ": " + y);
            n++;
            y += f(y,t)*dt;
        }
    }
}

Here are some results at each for different numbers of steps:
0: 3.0
5: 3.0682513992369205
10: 3.11812938865782
15: 3.1385875952782825
20: 3.141543061526081
25: 3.141592653650948
30: 3.1415926535886047
35: 3.1415926535970526
40: 3.1415926517316737  // getting pretty close!
45: 3.1416034165087647  // uh oh
50: 2.0754887983317625
55: 49.866227663669584
60: 64.66835482328707
65: 57.249212987256286
70: 9.980977494635624
75: 35.43035516640032
80: 51.984982646834
85: 503.8854575676292
90: 1901.3240821223753
95: 334.1514462091029
100: -1872.5333656701248

How it works:

  That differential equation is well known because it is extremely difficult to integrate correctly. While for small t values naive integration will produce acceptable results, most integration methods exhibit extreme instability as t gets very large.

Awesome answer. Do you have any link about what makes the equation behave like this?

@UriZarfaty This wikipedia article explains it pretty well: http://en.wikipedia.org/wiki/Stiff_equation

What is n?...

@ColeJohnson I'm just using that to track the number of iterations for purposes of display.

@AJMansfield I meant: it's not declared anywhere. Your for deceleration uses t, but your loop uses n.

@ColeJohnson I just fixed it.

I think your differential equation should read dy/dt = sin(y)*exp(t).

@DavidZhang Yes, you are correct. I will fix it as soon as I can.

@DavidZhang Fixed.

Code:
var pi = function(m) {
  var s2 = 1, s1 = 1, s = 1;
  for (var i = 0; s >= 0; ++i) {
    s = s1 * 2 - s2 * (1 + m*m);
    s2 = s1;
    s1 = s;
  }
  return i*m*2;
};

I basically discovered this sequence by accident. It starts out as 1, 1 and every term after that s(n) is given by s(n) = 2*s(n - 1) - s(n - 2) * (1 + m*m). The end result is the smallest n such that s(n) < 0 multiplied by 2m. As m gets smaller, it should get more and more accurate.
pi(1/100) --> 3.14
pi(1/1000) --> 3.14
pi(1/10000) --> 3.1414
pi(1/100000) --> 3.14158
pi(1/1000000) --> 3.141452 // what?
pi(1/10000000) --> 3.1426524 // .. further away from pi

I'm pretty sure these are floating point errors as (1 + m*m) gets close to one, but I'm not sure. Like I said, I stumbled on this by accident. I'm not sure of its official name. Don't try this with an m too small or it will run forever (if 1 + m*m == 1 due to m being so small).
If anyone knows the name of this sequence or why it behaves like this, I would appreciate it.

I think this is due to cancellation, which is a loss of digits when subtracting two almost equal numbers. S1 and s2 are almost equal after an iteration.

I'm yet to find out how it works, but it reminds me of something I once did: I repeatedly took the cumulative sum of a noisy signal and normalized it to mean 0, max value 1. This would converge to a sine wave, since that's the only signal that is its own anti-derivative (with a phase offset).

I asked it over at math.SE, and got this answer.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Vampire Compatibility
A little known fact about vampires is that they must drink the blood of victim that has a compatible donor blood type.  The compatibility matrix for vampires is the same as the regular red blood cell donor/recipient matrix.  This can be summarized by the following American Red Cross table
Type    You Can Give Blood To    You Can Receive Blood From
A+      A+, AB+                  A+, A-, O+, O-
O+      O+, A+, B+,AB+           O+, O-
B+      B+, AB+                  B+, B-, O+, O-
AB+     AB+                      everyone
A-      A+, A-, AB+, AB-         A-, O-
O-      everyone                 O-
B-      B+, B-, AB+, AB-         B-  O-
AB-     AB+, AB-                 AB-, A-, B-, O-

Challenge
Write a function or program that takes a blood type as input and outputs two lists:

the unordered list of types that may receive donation of the input type
the unordered list of types that may give donation to the input type

If you write a function, then please also provide a test program to call that function with a few examples, so I can easily test it.  In this case, the test program would not count towards your score.
Input
Input must be a string representing exactly one of the 8 possible red blood cell types O− O+ A− A+ B− B+ AB− AB+.  Input may be given via the normal methods (STDIN, command-line args, function args, etc).
If any other input is given then the program/function must return empty output or throw an error.  Normally strict input-checking is not great in code-golf questions, but I felt given the life-death implications of getting blood types wrong that I should add this rule.
Output
Output will be two human-readable lists of blood types in whatever format is suitable for your language.  In the special cases where one of the output list contains all 8 types, this list may optionally be replaced with a single item list containing everyone.
Normal output will go to one of the normal places (STDOUT, function return, etc).
Other rules

Standard loopholes are banned
You may use whatever pre-existing 3rd party libraries you need, so long as they are not designed explicitly for this purpose.

Examples

For input AB-, the two output lists would be: {AB+, AB-}, {AB-, A-, B-, O-}
For input AB+, the two output lists would be: {AB+}, {O−, O+, A−, A+, B−, B+, AB−, AB+} or {AB+}, {everyone}

Personal note: Please consider donating blood if you are able to.  Without the transfusion I received a few years ago, I might not be here today, so I feel very grateful towards those who are able to donate!

@MartinBüttner Actually I will accept both.  Most likely the 2nd form will yield shorter code in most languages, but perhaps there will be some special case where using the first form could be shorter.

Tangentially related - this brilliant answer http://worldbuilding.stackexchange.com/a/11203/2094

Half the answers so far are function-only answers.  Please also consider this meta question: http://meta.codegolf.stackexchange.com/questions/4909/function-only-answers-to-function-or-program-questions-should-provide-a-test-pro

That fact is not so little-known.

@leftaroundabout Thanks - A Bit of Fry and Laurie has always been a favourite of mine!

Does anyone know if this array c=[9,15,12,8,153,255,204,136] can be encoded as a unicode string? Such that I could iterate with ord(c[i])?

@mbomb007 See what the shell can give you printf %02x 9 15 12 8 153 255 204 136 | xxd -p -r.  Also consider the hex representations of these numbers?  Can you multiply by 17?

A picky vampire, eh? Dracula is turning in his casket. Also, the title sounds like the name of a retired goth-rock-band.

Clip, 69
*cTx\{fFx`Tf[tFtx}T`[Fx[y!VVx"O-"Vy"O-"}[TC"A+ B+ AB+ O+ A- B- AB- O-

Input: AB-
Output: {{"AB+", "AB-"}, {"A-", "B-", "AB-", "O-"}}
Explanation
A blood type x can give to y if all of x's antigens are included in y. The program defines the function F as whether x can give to y, and T as the list of types.
*cTx                 .- If T contains x (the input)         -.
    \                .- Print                               -.
     {             ` .- a list of                           -.
      fFx`T          .- filter each t in T with F(x,t)      -.
           f[tFtx}T  .- filter each t in T with F(t,x)      -.

[Fx[y              } .- F is a function of x and y          -.
     !V              .- all letters of ... are included in ...   -.
       Vx"O-"        .- x, with O and - removed             -.
             Vy"O-"  .- y, with O and - removed             -.

[TC"A+ B+ AB+ O+ A- B- AB- O-   .- T is the list of types -.

Java 8, 373
import java.util.*;void f(String s){List<String>l=new ArrayList(Arrays.asList("A+,B+,AB+,O+,A-,B-,AB-,O-".split(","))),m=new ArrayList(l);int i=l.contains(s)?1:0/0;l.removeIf(x->g(s,x)<1);m.removeIf(x->g(x,s)<1);System.out.print(l+","+m);}int g(String s,String t){for(char c:s.replaceAll("O|-","").toCharArray())if(!t.replaceAll("O|-","").contains(""+c))return 0;return 1;}

Explanation
void f(String s) {
    List<String> l = new ArrayList(Arrays.asList("A+,B+,AB+,O+,A-,B-,AB-,O-".split(","))),
                 m = new ArrayList(l);
    int i = l.contains(s) ? 1 : 0 / 0;
    l.removeIf(x -> g(s, x) < 1);
    m.removeIf(x -> g(x, s) < 1);
    System.out.print(l + "," + m);
}

int g(String s, String t) {
    for (char c : s.replaceAll("O|-", "").toCharArray()) {
        if (!t.replaceAll("O|-", "").contains("" + c)) {
            return 0;
        }
    }
    return 1;
}

Run it here: http://repl.it/e98/1
Note that static had to be added to each method to call them from the main method.

I added a link to an easily-run program for you. Edit the string parameter inside the function call in the main method to see the other inputs' outputs.

Pyth, 61 59 50
L-{b"O-"M!-yGyHJmsd*c"A O B AB"d"+-"I}zJfgzTJfgYzJ

Run it here.
Explanation:
L-{b"O-"                         Create function y(b) that makes a set from b's
                                 characters minus O and -.
M!-yGyH                          Create function g(G,H) that checks if y(G) is
                                 a subset of y(H).
J                                Assign to J...
 msd                             The concatenation of every element in...
    *c"A O B AB"d"+-"            The Cartesian product of A O B AB and + -.
I}zJ                             If input in J then...
    fgzTJ                        Print all elements e in J if g(input, e).
    fgYzJ                        Print all elements e in J if g(e, input).

@user23013 Thanks for the edit. It definitely should've been Cartesian :)

Prolog, 119 110 bytes
u(A,B):-member(A:B,[a:ab,b:ab,o:a,o:b,o:ab]);A=B,member(A,[a,ab,b,o]).
g(X,Y):-(X= -A;X=A),(Y= -B;Y=B),u(A,B).

Remarks:

Blood types have the following properties: everytime you have a - (e.g. a-), you can give to the same people as the one who have positive equivalent of your group (e.g. a), as well as their negative counterpart (e.g. a gives to ab, so a- gives to ab and ab-). Based on this property, and abusing the notations a little bit to make use of the minus and plus operators, we can factor a lot of cases. Please tell me if you find it acceptable. If you prefer having the original (postfix) syntax, here is a non-golfed version:
blood(X):-member(R,['a+','o+','b+','ab+','a-','b-','ab-']).
give('o-',R):-blood(R).
give(X,X):-blood(X).
give('a+','ab+').
give('b+','ab+').
give('o+','a+').
give('o+','b+').
give('o+','ab+').
give('a-','a+').
give('a-','ab+').
give('a-','ab-').
give('b-','b+').
give('b-','ab+').
give('b-','ab-').
give('ab-','ab+').

This is Prolog, so the interactive environment allows to query everything as requested (see example below). Granted, we don't have lists strictly as an output, but this is equivalent.
We also naturally handle error cases as a consequence.

Example
donors(X,L) :- findall(Y,g(Y,X),L).
receivers(X,L) :- findall(Y,g(X,Y),L).

test :-
    member(X,[a,o,b,ab,-a,-o,-b,-ab]),
    donors(X,D),
    receivers(X,R),
    writeln(X:give_to(R):receive_from(D)),
    fail.
test.

Then, we execute test:
a : give_to([ab, a]) : receive_from([o, a])
o : give_to([a, b, ab, o]) : receive_from([o])
b : give_to([ab, b]) : receive_from([o, b])
ab : give_to([ab]) : receive_from([a, b, o, ab])
-(a) : give_to([+(ab), +(a), -(ab), -(a)]) : receive_from([-(o), -(a)])
-(o) : give_to([+(a), +(b), +(ab), +(o), -(a), -(b), -(ab), -(o)]) : receive_from([-(o)])
-(b) : give_to([+(ab), +(b), -(ab), -(b)]) : receive_from([-(o), -(b)])
-(ab) : give_to([+(ab), -(ab)]) : receive_from([-(a), -(b), -(o), -(ab)])

... which, without proper formatting, is the same matrix as the one given in the question.
Details
The predicate g/2 is the give relationship: g(X,Y) means people of blood type X may give blood to people of blood type Y.
Find receivers for group a:
[eclipse]: g(a,R).

R = ab
Yes (0.00s cpu, solution 1, maybe more) ? ;

R = a
Yes (0.00s cpu, solution 2)

Find receivers for orange_juice (should fail):
[eclipse] g(orange_juice,L).

No (0.00s cpu)

Find donors for O-:
[eclipse] g(X,-o).

X = -(o)
Yes (0.00s cpu)

Who can give what? :
[eclipse] g(X,Y).

.... 27 answers ....

We do not go into an infinite recursion loop (it was the case in preliminary tests).

CJam, 64 bytes
"AB"_a+'O+"+-"m*:s:TT{}+Tqa#=a+T4=f&_)f{\-!}\)f-:!]{T]z::*La-p}/

The m*:s part comes from Martin's CJam answer. (I didn't read the other parts yet.)
There will be still some serious problems because they'll be never sure about the order of the two lists. And Block ArrayList & might be implemented in later versions of CJam.
Explanation
"AB"_a+'O+         " Generate ['A 'B \"AB\" 'O]. ";
"+-"m*:s:T         " Generate the list of blood types and store in T. ";
T{}+
    Tqa#           " Find the input in T. ";
=                  " Find the blood type by the index.
                     If not found, return a block to cause an error. ";
a+                 " Append the verified input to T. ";
T4=                " AB+. ";
f&                 " Intersect each blood type with AB+. ";
_)f{\-!}           " Check emptiness of input - each item. ";
\)f-:!             " Check emptiness of each item - input. ";
]{                 " For both lists: ";
    T]z::*         " Replace items in T where there is a 0 with empty strings. ";
    La-            " Remove empty strings. ";
    p              " Print. ";
}/

Javascript, 167
p=function(t){o="";if((x=(l="O- O+ B- B+ A- A+ AB- AB+".split(" ")).indexOf(t))<0)return;n=2;while(n--){y=8;while(y--)if([y,x][n]-(y&x)==0)o+=" "+l[y];o+=";"}return o}

ungolfed:
function p(btype){
    output = "";
    btypeList = "O- O+ B- B+ A- A+ AB- AB+".split(" ");

    btypeInt = btypeList.indexOf(btype);
    // thus we have the scheme
    // btypeInt = 0b(has A antigen)(has B antigen)(has rhesus antigen)

    if(btypeInt < 0) // i.e. broken blood type string
        return;

    for(receiving = 7; receiving >= 0; receiving--)
        if(giving - (receiving & btypeInt) == 0)
            // i.e. the receiving person has at least all the antigens of our donor
            output += " " + btypeList[receiving];

    output += ";";

    for(giving = 7; giving >= 0; giving--)
        if(btypeInt - (receiving & btypeInt) == 0)
            // i.e. the giving person has no antigens that our patient doesn't have
            output += " " + btypeList[receiving];

    return output;
}

testing function:
function tester(){
    btypeList = "O- O+ B- B+ A- A+ AB- AB+".split(" ");
    for(i=0; i<8; i++){
        console.log("Patient is " + btypeList[i])
        console.log(p(btypeList[i]))
    }
    console.log("Erroneous blood type => returns void:")
    console.log(p("asdf"))
}

Encoding the blood type in binary has the advantage that another antigen (e.g. the Kell antigen) is easily incorporated into the code by just adding another bit.

Donate blood in Zurich, CH: Blutspende Zürich

You can use "O-O+B-B+A-A+AB-AB+".match(/\w+\W/g) instead of "O- O+ B- B+ A- A+ AB- AB+".split(" ") to save 2 chars.

Or you can save exactly the same by making the delimiter a number "O-1O+1B-1B+1A-1A+1AB-1AB+".split(1) and using => function should save some too.

Yes, but @Oriol's can be further shortened in the regular expression by 1 character: /\w+./g

Always use for(;;) instead of while(). At least same length, but can be shorter. n=2;while(n--) => for(n=2;n--;)

All in all, very clever. Can be shortened to 147 using standard golf tricks: http://jsfiddle.net/j2hep8e8/2/

Thanks for the hints everyone! I won't update my entry as these aren't my own contributions, but learning new tricks is always nice ;)

CJam, 94 bytes
Wow, this is long... while I think I could probably golf this approach below 80, I think I might have done better by first computing the matrix and then simply picking out the correct row and column. Anyway, here it is:
'O'A'B"AB"]:A"+-"m*:sq_a@&!!*_)'++_&\"AB"&A{1$\-!},\;\m*::+p)'-+_&\"AB"&A1>{1$-!},'O+\;\m*::+p

Test it here.
I'll add an explanation when I'm done golfing.

Groovy, 115
x={i=(l=('O-O+B-B+A-A+AB-AB+'=~/\w+./)[0..7]).indexOf(it);f=(0..7).&findAll;i<0?[]:[l[f{!(~it&i)}],l[f{!(it&~i)}]]}

The idea is to encode A, B and rhesus factor as one bit each. We can then inverse the bits to get all the antigens on the receiving side and use it to check that there is no corresponding antibodies on the giving side. This is more or less the same as the existing JavaScript solution.
Sample execution
groovy> println x("AB+")
groovy> println x("AB-")
groovy> println x("A+")
groovy> println x("A-")
groovy> println x("B+")
groovy> println x("B-")
groovy> println x("O+")
groovy> println x("O-")
groovy> println x("X")

[[AB+], [O-, O+, B-, B+, A-, A+, AB-, AB+]]
[[AB-, AB+], [O-, B-, A-, AB-]]
[[A+, AB+], [O-, O+, A-, A+]]
[[A-, A+, AB-, AB+], [O-, A-]]
[[B+, AB+], [O-, O+, B-, B+]]
[[B-, B+, AB-, AB+], [O-, B-]]
[[O+, B+, A+, AB+], [O-, O+]]
[[O-, O+, B-, B+, A-, A+, AB-, AB+], [O-]]
[]

Ruby, 237 232 223 221 210 207 bytes
Fixed some extraneous backslashes in the regular expressions and made it so it just prints out the lists as opposed to storing them to variables and then printing them. Sometimes you miss the obvious things when trying to golf!
o=->b{Regexp.new b.gsub(?O,?.).gsub(?+,'.?\\\+').gsub'-','.?(\W)'};b=gets.chop;t=["A+","B+","AB+","O+","A-","B-","AB-","O-"];exit if !t.include? b;p t.reject{|x|!x.match o.(b)};p t.reject{|x|!b.match o.(x)}

Ungolfed:
#!/usr/bin/ruby
b=gets.chomp;
types = ["A+","A-","B+","B-","AB+","AB-","O+","O-"];
exit if !types.include?(b);
regex1 = Regexp.new b.gsub("O",".").gsub('+','.?\\\+').gsub('-','.?(\\\+|\\\-)')
donate = types.reject {|x|!x.match(regex1)};
p donate;
receive = types.reject {|x| regex2 = Regexp.new x.gsub("O",".").gsub('+','.?\\\+').gsub('-','.?(\\\+|\\\-)'); !b.match(regex2)};
p receive;

Basically, I construct a custom regular expression for the blood type entered to check if you can donate to another blood type. I then iterate through the blood types and apply that same regex to them and check if they can donate to the one specified.
This can probably be golfed down even more. This is my first time attempting code golf, heh.

PHP - 215 212 206 bytes
function($t){$c=[9,15,12,8,153,255,204,136];if(($a=array_search($t,$l=split(1,'A+1O+1B+1AB+1A-1O-1B-1AB-')))===!1)die;foreach($l as$k=>$v){if($c[$a]&1<<$k)$x[]=$v;if($c[$k]&1<<$a)$y[]=$v;}var_dump($x,$y);}

Here is the ungolfed version:
function ($type)
{
    $typesList = ['A+', 'O+', 'B+', 'AB+', 'A-', 'O-', 'B-', 'AB-'];
    $donationCompatibilityList = [
        0b00001001,
        0b00001111,
        0b00001100,
        0b00001000,
        0b10011001,
        0b11111111,
        0b11001100,
        0b10001000,
    ];

    $idType = array_search($type, $typesList);
    if ($idType === false) {
        die;
    }

    $canGiveToList = [];
    $canReceiveFromList = [];
    foreach ($typesList as $currentIdType => $currentType)
    {
        if ($donationCompatibilityList[$idType] & 1 << $currentIdType ) {
            $canGiveToList[] = $currentType;
        }

        if ($donationCompatibilityList[$currentIdType ] & 1 << $idType) {
            $canReceiveFromList[] = $currentType;
        }
    }

    var_dump($canGiveToList, $canReceiveFromList);
}

Thanks to manatwork for saving 4 bytes.

The split by integer trick works in PHP too: explode(1,'A+1O+1B+1AB+1A-1O-1B-1AB-'). And as we not necessarily keep up with nice coding habits, sometimes we use deprecated features, like the split() function.

@manatwork Well spotted! I've edited my answer, thanks.

Python 2, 168 bytes
This is the same method as Blackhole's answer. Exits with an error if the parameter is not found in the list of types.
def f(t):l='A+ O+ B+ AB+ A- O- B- AB-'.split();c=[9,15,12,8,153,255,204,136];i=l.index(t);print[s for s in l if c[i]&1<<l.index(s)],[s for s in l if c[l.index(s)]&1<<i]

Less golfed:
def f(t):
    l = 'A+ O+ B+ AB+ A- O- B- AB-'.split()
    c = [9, 15, 12, 8, 153, 255, 204, 136]
    i = l.index(t)
    x = [s for s in l if c[i] & 1 << l.index(s)]
    y = [s for s in l if c[l.index(s)] & 1 << i]
    print x, y

Run it here: http://repl.it/eaB
I also tried a couple other slight changes, but couldn't get it any shorter...
#172 bytes
def f(t):l='A+ O+ B+ AB+ A- O- B- AB-'.split();c=[9,15,12,8,153,255,204,136];a=lambda x:l.index(x);i=a(t);print[s for s in l if c[i]&1<<a(s)],[s for s in l if c[a(s)]&1<<i]

#171 bytes
def f(t):l='A+ O+ B+ AB+ A- O- B- AB-'.split();c=[9,15,12,8,153,255,204,136];a=lambda x:l.index(x);print[s for s in l if c[a(t)]&1<<a(s)],[s for s in l if c[a(s)]&1<<a(t)]

Python, 187 bytes
Different approach:
def D(a,b):X=lambda c:c in a and 1-(c in b);return(X('A')+X('B')+X('+'))<1
T="O- O+ A- A+ B- B+ AB- AB+".split()
X=lambda t:(0,([u for u in T if D(t,u)],[u for u in T if D(u,t)]))[t in T]

Can probably be golfed a bit more.
Test:
for t in T + ["zz"]:
    print t, X(t)

Output:
O- (['O-', 'O+', 'A-', 'A+', 'B-', 'B+', 'AB-', 'AB+'], ['O-'])
O+ (['O+', 'A+', 'B+', 'AB+'], ['O-', 'O+'])
A- (['A-', 'A+', 'AB-', 'AB+'], ['O-', 'A-'])
A+ (['A+', 'AB+'], ['O-', 'O+', 'A-', 'A+'])
B- (['B-', 'B+', 'AB-', 'AB+'], ['O-', 'B-'])
B+ (['B+', 'AB+'], ['O-', 'O+', 'B-', 'B+'])
AB- (['AB-', 'AB+'], ['O-', 'A-', 'B-', 'AB-'])
AB+ (['AB+'], ['O-', 'O+', 'A-', 'A+', 'B-', 'B+', 'AB-', 'AB+'])
zz 0

PHP (287 bytes):
Yeah, this is pretty long, but it works as expected.
It may be possible to shorten a lot:
!preg_match('@^(AB?|B|O)[+-]$@',$t=$_GET[T])&&die("$t invalid");$S=array_flip($D=split(0,'O+0A+0B+0AB+0O-0A-0B-0AB-'));$L=[[1230,40],[13,1504],[23,2604],[3,$r=12345670],[$r,4],[1537,54],[2637,64],[37,7564]];for($j=0;$j<2;){foreach(str_split($L[$S[$t]][$j++])as$v)echo$D[$v].' ';echo'
';}

This is not easy to read and was't easy to write.
It works as intended, outputting the ones you can give to and the ones you can receive from on another line.
This requires a URL parameter T= with the type.

CJam, 80 bytes
This is still too long. Probably I can shave off 4 to 5 bytes more.
U1023_XKC30D]2/La+"AB"a"OAB"1/+:Mr):P;a#=_P"+-":G&+!!{AfbMff=G1/Pf|]z{~m*:s}%}*`

For any invalid input, either prints an empty array, or throws an error.
Try it online here or run the whole test suite

Is the XKCD in the begging intended?

@Ypnypn begging ? I did not intend to initially, but it turned out like that. Maybe the world is trying to tell us something...

Sorry, I meant beginning.

APL, 66
(↓⊃∧/(↓t∘.∊v)(≥,[.5]≤)¨t∊⊃v⌷⍨v⍳⊂⍞)/¨⊂v←,'+-'∘.,⍨('O'∘,,⊂)2↑t←'AB+'

Try it here.

Maybe that's 66 characters, but definitely not 66 bytes. The question doesn't say what's used to score though.

@orlp [tag:code-golf] is scored in bytes by default (see the tag wiki). But it is said there is an APL code page where one character is one byte. I don't know exactly which APL code page is used nowadays, though.

@orlp "bytes", but not "UTF-8 bytes". Here is a code page containing all of these characters.

C, 224
#define d(x)for(i=0;i<8;i++)if((i x j)==j)printf("%s%s%s%c ",i&2?"A":"",i&4?"B":"",i&6?"":"0","-+"[i&1]);puts("");
main(i,j){char d[4],*c=&d;scanf("%s",c);j=(c[2]?c++,2:0)+(c[1]-'+'?0:1)+(*c>='A'?2:0)+(*c>'A'?2:0);d(&)d(|)}

De-golfed it shows:
/* j = 1*(has+) + 2*(hasA) + 4*(hasB) */
#define d(x) for(i=0;i<8;i++) \
                 if((i x j)==j) \
                      printf("%s%s%s%c ",i&2?"A":"",i&4?"B":"",i&6?"":"0","-+"[i&1]); \
             puts("");

main(i,j)
{
    char d[4], *c=&d;
    scanf("%s",c);

    j= (c[2]? (c++,2):0)            /* ABx */
            + (c[1]-'+'?0:1)
            + (c[0]>='A'?2:0)
            + (c[0]>'A'?2:0);

    // print possible receipients, and then donators
    d(&)
    d(|)
}

Perl, 107 112
Finally encoding the type names in numbers gave the shorter code.
#!perl -p
$x=y/AB+/421/r%9;@a=grep{~$x&$_%9||push@b,$_;!($x&~($_%9))}map{("$_-",$_.1)}0,2,4,42;$_="@a
@b";y/421/AB+/

Older version
#!perl -p
$x=y/AB+/421/r%9;@a=grep!($x&~$_),0..7;@b=grep!(~$x&$_),0..7;$_="@a
@b";s/\d/(map{("$_+","$_-")}0,A,B,AB)[$&]/eg

Pyth, 58
Partly the same as orlp's solution, but somewhat different and completely self-designed.
M&n+eGeH"+-"!f!}T+H\OPGJsm,+d\++d\-c"O A B AB"dfgzYJfgZzJJ

Explanation
M                          create a function g(G,H) that returns
  n+eGeH"+-"                 G[-1] + H[-1] is not "+-"
 &                          and
            !f!}T+H\OPG      chars of G[:-1] not in H + "O" is falsy (empty)
J                          J =
 s                          merge
  m                          map
   ,+d\++d\-                  lambda d: (d + "+", d + "-")
            c"O A B AB"d      over ["O", "A", "B", "AB"]
fgzYJ                      print all J's items x where g(input, x)
fgZzJ                      print all J's items x where g(x, input)

J, 120 bytes
   f=.3 :';"1(2 8$,(s-:"*<y,'' '')#8 2 8$#:213472854600871062656691437010712264449x)#s=.<;.2''A+ B+ AB+ O+ A- B- AB- O- '''

   f 'A+'
A+ AB+
A+ O+ A- O-

   f 'AB-'
AB+ AB-
A- B- AB- O-

The function fails on invalid inputs. The big decimal number is the encoding of the full compatibility matrix.
(Very long solution for multiple reasons.)
Try it online here.

05AB1E, 29 bytes
„ABD`'O)„+-âJÐIkVāY&èê,āY~èê,

Try it online!

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Adding Numbers with Regex
I want to try a new type of regex golf challenge, which asks you to solve nontrivial computational tasks with nothing but regex substitution. To make this more possible and less of a chore, you will be allowed to apply several substitutions, one after the other.
The Challenge
We'll start simple: given a string containing two positive integers, as decimal numbers separated by a ,, produce a string containing their sum, also as as a decimal number. So, very simply
47,987

should turn into
1034

Your answer should work for arbitrary positive integers.
The Format
Every answer should be a sequence of substitution steps, each step consisting of a regex and a replacement string. Optionally, for each of those steps in the sequence, you may choose to repeat the substitution until the string stops changing. Here is an example submission (which does not solve the above problem):
Regex    Modifiers   Replacement   Repeat?
\b(\d)   g           |$1           No
|\d      <none>      1|            Yes
\D       g           <empty>       No

Given the input 123,456, this submission would process the input as follows: the first substitution is applied once and yields:
|123,|456

Now the second substitution is applied in a loop until the string stops changing:
1|23,|456
11|3,|456
111|,|456
111|,1|56
111|,11|6
111|,111|

And lastly, the third substitution is applied once:
111111

Note that the termination criterion for loops is whether the string changes, not whether the regex found a match. (That is, it might also terminate if you find a match but the replacement is identical to the match.)
Scoring
Your primary score will be the number of substitution steps in your submission. Every repeated substitution will count for 10 steps. So the above example would score 1 + 10 + 1 = 12.
In the (not too unlikely) case of a tie, the secondary score is the sum of the sizes of all steps. For each step add the regex (without delimiters), the modifiers and the substitution string. For the above example this would be (6 + 1 + 3) + (3 + 0 + 2) + (2 + 1 + 0) = 18.
Miscellaneous Rules
You may use any regex flavour (which you should indicate), but all steps must use the same flavour. Furthermore, you must not use any features of the flavour's host language, like replacement callbacks or Perl's e modifier, which evaluates Perl code. All manipulation must happen exclusively through regex substitution.
Note that it depends on your flavour and modifiers whether each single replacement replaces all occurrences or only a single one. E.g. if you choose the ECMAScript flavour, a single step will by default only replace one occurrence, unless you use the g modifier. On the other hand, if you're using the .NET flavour, each step will always replace all occurrences.
For languages which have different substitution methods for single and global replacement (e.g. Ruby's sub vs. gsub), assume that single replacement is the default and treat global replacement like a g modifier.
Testing
If your chosen flavour is either .NET or ECMAScript, you can use Retina to test your submission (I'm being told, it works on Mono, too). For other flavours, you will probably have to write a small program in the host language which applies the substitutions in order. If you do, please include this test program in your answer.

If anyone has a good idea what to call this type of challenge, leave a comment! :) (Just in case I'm doing more of these in the future.)

Those who like this might also enjoy Add without addition and Multiply without numbers

Is Retina's regex "flavour" a valid submission? :P (I'm fairly proud of myself for managing to add two numbers at all, let alone golf it.)

@icrieverytim Retina's flavour is just the .NET flavour.

But Retina has features .NET doesn't have, no?

@icrieverytim Not as far as the regex flavour is concerned. Just double-checked what challenge this is, and Retina does have additional substitution features, which would be relevant here. I guess you can use those, but please indicate that those features are newer than the challenge.

.NET flavor, score:2
Regex        Modifiers  Replacement  Repeat?
<empty>      <none>     9876543210   No
<see below>  x          <empty>      No

I'm not bothered to golf it yet, and x is just for ignoring whitespaces.
It firstly insert 9876543210 at each position, then delete the original characters and the characters those are not the current digit of the sum.
The big regex (1346 bytes without whitespaces and comments):
# If the length of the left number <= right number, delete every digit on the left.
.(?=.*,(?<=^(?<len>.)*,)(?<-len>.)*(?(len)(?!)))|

# Do the opposite if it is not the case.
.(?<=(?(len)(?!))(?<-len>.)*(?=(?<len>.)*$),.*)|

# Remove leading zeros.
(?<=(^|,).{9})0|

# Delete everything that is not the current digit of the sum.
.(?!
    # For digits in the left part:
    (?<cur>.){0,9}               # cur = the matched digit
    (?=(.{11})*,)                # and find the position before the next digit.
    (?<first>)                   # first = true
    (                            # Loop on the less significant digits:
        (?<cur>){10}             # cur += 10
        (?<=                     # cur -= the current digit in this number.
            (
                0|^|
                1(?<-cur>)|
                2(?<-cur>){2}|
                3(?<-cur>){3}|
                4(?<-cur>){4}|
                5(?<-cur>){5}|
                6(?<-cur>){6}|
                7(?<-cur>){7}|
                8(?<-cur>){8}|
                9(?<-cur>){9}
            )
            .{10}
        )
        (?=
            (?<pos>.{11})*,      # pos = which digit it is.
            .*$(?<=              # cur -= the current digit in the other number.
                (
                    0|,|
                    1(?<-cur>)|
                    2(?<-cur>){2}|
                    3(?<-cur>){3}|
                    4(?<-cur>){4}|
                    5(?<-cur>){5}|
                    6(?<-cur>){6}|
                    7(?<-cur>){7}|
                    8(?<-cur>){8}|
                    9(?<-cur>){9}
                )
                .{10}
                (?(pos)(?!))     # Assert pos = 0.
                                 # Skip pos input digits from the end.
                                 # But stop and set pos = 0 if the comma is encountered.
                ((?<-pos>\d{11})|(?<=(?>(?<-pos>.)*),.{10}))*
            )
        )
        (?(first)                # If first:
            (?>((?<-cur>){10})?) #  cur -= 10 in case there is no carry.
                                 #  Assert cur = 0 or 1, and if cur = 1, set cur = 10 as carry.
            (?(cur)(?<-cur>)(?(cur)(?!))(?<cur>){10})
            (?<-first>)          #  first = false
        |                        # Else:
                                 #  cur is 10 or 20 at the beginning of an iteration.
                                 #  It must be 1 to 11 to make the equation satisfiable.
            (?<-cur>)            #  cur -= 1
            (?(cur)              #  If cur > 0:
                                 #   cur -= max(cur, 9)
                (?(cur)(?<-cur>)){9}
                (?(cur)          #   If cur > 0:
                                 #    Assert cur = 1 (was 11) and set cur = 10.
                    (?<-cur>)(?(cur)(?!))(?<cur>){10}
                |                #   Else:
                    .*(?=,)      #    cur was 2 to 10, break from the loop.
                )
            )                    #  Else cur is 0 (was 1) and do nothing.
        )
        (.{11}|,)                # Jump to the next digit.
    )*(?<=,)(?(cur)(?!))         # End the loop if it is the last digit, and assert cur = 0.
|
    # Do the same to the right part. So the sum will be calculated two times.
    # Both are truncated to the original length of the number on that side + 1.
    # Only the sum on the longer side will be preserved in the result.
    (?<cur>\d){0,9}
    (?=(\d{11})*$)
    (?<first>)
    (
        (?<cur>){10}
        (?<=
            (
                0|,|
                1(?<-cur>)|
                2(?<-cur>){2}|
                3(?<-cur>){3}|
                4(?<-cur>){4}|
                5(?<-cur>){5}|
                6(?<-cur>){6}|
                7(?<-cur>){7}|
                8(?<-cur>){8}|
                9(?<-cur>){9}
            )
            .{10}
        )
        (?=
            (?<pos>.{11})*$
            (?<=
                (
                    0|^|
                    1(?<-cur>)|
                    2(?<-cur>){2}|
                    3(?<-cur>){3}|
                    4(?<-cur>){4}|
                    5(?<-cur>){5}|
                    6(?<-cur>){6}|
                    7(?<-cur>){7}|
                    8(?<-cur>){8}|
                    9(?<-cur>){9}
                )
                .{10}
                (?(pos)(?!))
                ((?<-pos>\d{11})|(?<=^.{10})(?=(?>(?<-pos>.)*)))*
                ,.*
            )
        )
        (?(first)
            (?>((?<-cur>){10})?)
            (?(cur)(?<-cur>)(?(cur)(?!))(?<cur>){10})
            (?<-first>)
        |
            (?<-cur>)
            (?(cur)
                (?(cur)(?<-cur>)){9}
                (?(cur)
                    (?<-cur>)(?(cur)(?!))(?<cur>){10}
                |
                    .*$(?<end>)
                )
            )
        )
        (.{11}|$(?<end>))
    )*(?<-end>)(?(cur)(?!))
)

This made me think of the final level of Manufactoria... But I think .NET regex, which is obviously no longer "regular", can solve any problems in PH. And this is just an algorithm in L.

All hail .NET balancing groups.

First I thought my five-step process was pretty good. Then I saw someone claim a solution with half the length. Then... this. Does this even count as a regex?

@JanDvorak For the theoretical "regular expression", no. For "regex", yes, everybody call this a regex, and almost every regex flavor has something like this. Microsoft still call them "regular expressions" officially.

Wow, this is amazing work!

Score: 24
I think this works...
Regex                                                                                Modifiers   Replacement             Repeat?
(?|(\d*)(\d)(,\d*)(\d)|(^,?\d*)(\d)|, |^,)                                                                                <none>      $1$3 $2$4               Yes
$                                                                                <none>      ;111111111234567890     No
0|(?|(;.*)|9(?=.*(1{9}))|8(?=.*(1{8}))|7(?=.*(1{7}))|6(?=.*(1{6}))|5(?=.*(1{5}))|4(?=.*(1{4}))|3(?=.*(111))|2(?=.*(11)))    g           $1                      No
 1{10}                                                                                <none>      1                       Yes
 (?|1{9}(?=.*(9))|1{8}(?=.*(8))|1{7}(?=.*(7))|1{6}(?=.*(6))|1{5}(?=.*(5))|1{4}(?=.*(4))|1{3}(?=.*(3))|1{2}(?=.*(2))|)       g            $1                     No
 (?!\d)(?=.*(0))| |;.*                                                                                g           $1                      No

I haven't spent much time golfing the individual regular expressions yet. I will try to post an explanation soon, but it's getting late now. In the meantime, here's the result between each step:
'47,987'
' 9 48 77'
' 9 48 77;111111111234567890'
' 111111111 111111111111 11111111111111;111111111234567890'
'1  111 1111;111111111234567890'
'1  3 4;111111111234567890'
'1034'

Full perl program:
$_ = <>;
chomp;

do {
    $old = $_;
    s/(?|(\d*)(\d)(,\d*)(\d)|(^,?\d*)(\d)|, |^,)/$1$3 $2$4/;
} while ($old ne $_);

s/$/;111111111234567890/;

s/0|(?|(;.*)|9(?=.*(1{9}))|8(?=.*(1{8}))|7(?=.*(1{7}))|6(?=.*(1{6}))|5(?=.*(1{5}))|4(?=.*(1{4}))|3(?=.*(111))|2(?=.*(11)))/$1/g;

do {
    $old = $_;
    s/ 1{10}/1 /;
} while ($old ne $_);

s/ (?|1{9}(?=.*(9))|1{8}(?=.*(8))|1{7}(?=.*(7))|1{6}(?=.*(6))|1{5}(?=.*(5))|1{4}(?=.*(4))|1{3}(?=.*(3))|1{2}(?=.*(2))|)/ $1/g;

s/ (?!\d)(?=.*(0))| |;.*/$1/g;

print "$_\n";

This looks a lot like my own proof of concept. :) I had 7 non-loop substitutions though, but I didn't try particularly hard to keep them down.

@MartinBüttner haha nice! I'm pretty sure my last two subs could be merged as well, but I've had enough for one day...

All leading spaces intentional ?

@Optimizer yes. I should have chosen a better character sorry.

Any regex flavor, 41
    s/0/d/g
    ...
    s/9/dxxxxxxxxx/g
rep s/xd/dxxxxxxxxxxx/g
    s/[d,]//g
rep s/(^|d)xxxxxxxxxx/xd/g
    s/(^|d)xxxxxxxxx/9/g
    ...
    s/(^|d)x/1/g
    s/d/0/g

Let's try unary. d serves for a digit order separator, x stores the value. First we unarise each digit, then we squeeze the x10 multipliers to the left, then drop all separators, then back-insert the multipliers, then convert each order back to digits.

.NET Regex, 14
Not as good as user23013's solution, but it was fun. None of the replacements have modifiers.
The reason for the .NET regex isn't because of balancing groups for once — I just tested with Retina, which uses .NET, and I also found that the variable length lookbehinds helped a lot.
Replacement 1 (repeat = no)
Regex:
\d(?=\d+$)|\d(?=\d+,)|\d(?=,(\d+)$)|(?<=(\d+),\d*)\d$

Replacement
0$1$2

Swap the two numbers, padding to have the same number of leading zeroes.
Replacement 2 (repeat = no)
Regex:
(\d+)

Replacement:
 $1

Add a space before each number
Replacement 3 (repeat = no)
$

Replacement:
&0 ~00000 ~00101 ~00202 ~00303 ~00404 ~00505 ~00606 ~00707 ~00808 ~00909 ~01001 ~01102 ~01203 ~01304 ~01405 ~01506 ~01607 ~01708 ~01809 ~01910 ~02002 ~02103 ~02204 ~02305 ~02406 ~02507 ~02608 ~02709 ~02810 ~02911 ~03003 ~03104 ~03205 ~03306 ~03407 ~03508 ~03609 ~03710 ~03811 ~03912 ~04004 ~04105 ~04206 ~04307 ~04408 ~04509 ~04610 ~04711 ~04812 ~04913 ~05005 ~05106 ~05207 ~05308 ~05409 ~05510 ~05611 ~05712 ~05813 ~05914 ~06006 ~06107 ~06208 ~06309 ~06410 ~06511 ~06612 ~06713 ~06814 ~06915 ~07007 ~07108 ~07209 ~07310 ~07411 ~07512 ~07613 ~07714 ~07815 ~07916 ~08008 ~08109 ~08210 ~08311 ~08412 ~08513 ~08614 ~08715 ~08816 ~08917 ~09009 ~09110 ~09211 ~09312 ~09413 ~09514 ~09615 ~09716 ~09817 ~09918 ~10001 ~10102 ~10203 ~10304 ~10405 ~10506 ~10607 ~10708 ~10809 ~10910 ~11002 ~11103 ~11204 ~11305 ~11406 ~11507 ~11608 ~11709 ~11810 ~11911 ~12003 ~12104 ~12205 ~12306 ~12407 ~12508 ~12609 ~12710 ~12811 ~12912 ~13004 ~13105 ~13206 ~13307 ~13408 ~13509 ~13610 ~13711 ~13812 ~13913 ~14005 ~14106 ~14207 ~14308 ~14409 ~14510 ~14611 ~14712 ~14813 ~14914 ~15006 ~15107 ~15208 ~15309 ~15410 ~15511 ~15612 ~15713 ~15814 ~15915 ~16007 ~16108 ~16209 ~16310 ~16411 ~16512 ~16613 ~16714 ~16815 ~16916 ~17008 ~17109 ~17210 ~17311 ~17412 ~17513 ~17614 ~17715 ~17816 ~17917 ~18009 ~18110 ~18211 ~18312 ~18413 ~18514 ~18615 ~18716 ~18817 ~18918 ~19010 ~19111 ~19212 ~19313 ~19414 ~19515 ~19616 ~19717 ~19818 ~19919

Add a carry bit (the &0) as well as the giant lookup table of <c> <a> <b> <carry of a+b+c> <last digit of a+b+c>.
Replacement 4 (repeat = yes)
Regex:
(?<=(\d),.*(\d)&)(\d)(?=.*~\3\1\2(.))|(\d)(?=,.*\d&)|(?<=\d,.*)(\d)(?=&)|^(?=.* .*(\d),.*(\d)&(\d).*~\9\7\8.(.))

Replacement:
$4$10

Keep taking the last digits of each number, and find their (sum, carry). Put the sum at the start of the string and replace the carry.
Replacement 5 (repeat = no)
Regex:
^0*| .*

Replacement:
<empty>

Clean up.
Example run
Repl no.        String
(input)         1428,57
1               000057,001428
2                000057, 001428
3                000057, 001428&0 <lookup table>
4               5 00005, 00142&1 <lookup table>
4               85 0000, 0014&0 <lookup table>
4               485 000, 001&0 <lookup table>
4               1485 00, 00&0 <lookup table>
4               01485 0, 0&0 <lookup table>
4               001485 , &0 <lookup table>
5               1485

(By combining a few of the steps I can get 12, but since it gets pretty messy and won't win anyway I think I'll keep this more elegant version up instead.)

Score: 50 40 31 21
Thanks for this excellent challenge.  This solution isn't very elegant, but, given the restrictions, I couldn't see any way to handle a digit generically in the output.
This solution features capture groups that sometimes don't match and relies on them being empty when that occurs.  This works in Perl, though it normally produces a warning.
Regex 1:     (((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0
Modifiers:   g
Replacement: <$1$2$3$4$5$6$7$8$9>
Repeat:      no

Regex 2:     (.*)<(\d*)>(,.*)<(\d*)>|(.*)<(\d*)>(.*)|(?:(^[^<]*)b(\d*)c)?(b)\d{9}(\d)(\d*)(c)
Modifiers:   none
Replacement: \8\1\5\3b$9$11\2\6\4c\7$10$12$13
Repeat:      yes

Regexes 3-12: ,?baaaaaaaaac
Modifiers:    g
Replacement:  9 etc. (one for each digit)

Full Perl code sample, with explanation and printing of intermediate results:
no warnings;
use 5.16.0;

$_ = '47,987';

#Convert numbers to beans
s/(((((((((9)|8)|7)|6)|5)|4)|3)|2)|1)|0/<$1$2$3$4$5$6$7$8$9>/g;

say;
my $last;

#Combine pairs of digits, starting with least significant.
do {
    $last=$_;
    s/(.*)<(\d*)>(,.*)<(\d*)>|(.*)<(\d*)>(.*)|(?:(^[^<]*)b(\d*)c)?(b)\d{9}(\d)(\d*)(c)/\8\1\5\3b$9$11\2\6\4c\7$10$12$13/;
    say;
}
while ($last ne $_);

#Convert beans back to numbers.
s/,?b\d{9}c/9/g;
s/,?b\d{8}c/8/g;
s/,?b\d{7}c/7/g;
s/,?b\d{6}c/6/g;
s/,?b\d{5}c/5/g;
s/,?b\d{4}c/4/g;
s/,?b\d{3}c/3/g;
s/,?b\d{2}c/2/g;
s/,?b\d{1}c/1/g;
s/,?bc/0/g;

say;

Update: I was able to combine two of the looping regexes together, saving 10.
Update 2: I managed to crack the input digit conversion with a single regex.
Update 3: I reduced to a single looping regex.

Interesting solution. :) What do the braces do in the replacement strings? Is ${1} different from $1? Also, you might want to include the byte count in case of ties.

@MartinBüttner, the braces simply separate the variable name from other characters that could be in a variable.

Ah, that makes sense. Thanks.

@MartinBüttner, I changed it to use \1, etc., instead, saving a few characters.


text:
Spiral Programming
Write a named function or program that accepts a single integer N and prints (to STDOUT) or returns (as a string) the first N bars of the spiral below, beginning with the vertical bar in the center and spiraling clockwise outward.
        _______________
       / _____________ \
      / / ___________ \ \
     / / / _________ \ \ \
    / / / / _______ \ \ \ \
   / / / / / _____ \ \ \ \ \
  / / / / / / ___ \ \ \ \ \ \
 / / / / / / / _ \ \ \ \ \ \ \
/ / / / / / / / \ \ \ \ \ \ \ \
| | | | | | | | | | | | | | | |
\ \ \ \ \ \ \___/ / / / / / / /
 \ \ \ \ \ \_____/ / / / / / /
  \ \ \ \ \_______/ / / / / /
   \ \ \ \_________/ / / / /
    \ \ \___________/ / / /
     \ \_____________/ / /
      \_______________/ /

You may assume that 0 < N <= 278. Your output cannot contain any whitespace in front of the leftmost character of the spiral. You may optionally print a single trailing newline.
For an input of 10, the correct output is
   _
  / \
  | |
\___/

For an input of 2, the correct output is
/
|

For an input of 20, the correct output is
  ___
 / _ \
/ / \ \
| | | |
\___/ /

An output that would be incorrect because the leftmost character is preceded by whitespace is
       ___
      / _ \
     / / \ \
     | | | |
     \___/ /

The winner is the shortest submission, in bytes.

This is a weird spiral, 6/8 sides grow larger per revolution and 2 remain size 1

@DevonParsons Think of it has a hexagonal spiral, where the vertical bars (|) are merely the closest character that can represent the meeting of a / and \.

CJam - 156 / 147
L{[W1]{:I0'|{IIW*:J'/}X*[0J'_]X2*I+*[J0_]I1={\}*{J_'\}X*0I0}%L*3/{~_{[UV@]a3$+}{;@}?V@+:V;U@+:U;}/}A,1>fX]ri=_z::e<2<f{[\\]z::-}$_W=0=)S50*a*\{~3$3$=\tt}/N*

Try it online
It works with inputs from 1 to 378 inclusive (100 more than required)
Using the latest committed (publicly available in hg) but unreleased CJam code at the time this challenge was posted, the solution can be shortened to 147 characters:
L{[W1]{:I0'|{IIW*:J'/}X*[0J'_]X2*I+*[J0_]I1={\}*{J_'\}X*0I0}%L*3/{~_{[UV@]a3$+}{;@}?V@+:V;U@+:U;}/}A,1>fX]ri=_:.e<2<f.-$_W=0=)S50*a*\{~3$3$=\tt}/N*

Explanation:
The program iteratively constructs all the spirals as arrays of [x y character] starting with [0 0 '|], gets the requested spiral, adjusts the coordinates so that the minimum x and y are 0, creates a matrix of spaces (with the correct number of rows and 50 columns) then sets the characters from the spiral and joins the rows with newlines.
L                   start with an empty array (spiral no. 0)
{…}A,1>fX           for X in 1..9 (A=10)
                    each X represents a full 360° tour with groups of X /'es and \'es
    [W1]{…}%        transform the array [-1 1] (W=-1) applying the block to each item
                    the block generates a series of triplets dx, dy, character
                    note: dx is down, dy is right; -1 handles ↑↗→↘, 1 handles ↓↙←↖
        :I          store the current item in I
        0'|         add 0 and |, which will form a triplet with the previous I
        {…}X*       repeat X times
            IIW*    add I and -I
            :J'/    also store -I in J, and add /
        [0J'_]      make an array [0 J _]
        X2*I+*      repeat the array X*2+I times
        [J0_]       make an array [J 0 0]
                    (a 0 instead of a character means only changing the position)
        I1={\}*     if I=1, swap the two arrays (the position adjustment is different
                    for the upper and lower horizontal sections)
        {…}X*       repeat X times
            J_'\    add J, J and \
        0I0         add 0, I and 0 (another position adjustment)
    L*              flatten the array (since we added a few inner arrays)
    3/              split into [dx dy char] triplets
    {…}/            for each triplet
        ~_          dump the 3 items on the stack and duplicate the character
        {…}         if the character is not 0
            [UV@]   make an array [U V char] (U and V are initially 0)
                    U represents "x" and V represents "y"
            a3$+    add it as an element to a copy of the previous spiral
        {…}         else
            ;@      pop the character and bring the previous spiral to the top
        ?           end if
        V@+:V;      V+=dy
        U@+:U;      U+=dx
]                   put all the spirals in an array
ri=                 read token, convert to integer and get that spiral
_z::e<              copy the spiral and get a triplet with the minimum values
2<                  keep only the first 2 items (xmin and ymin)
f{…}                for each triplet and the array [xmin ymin]
    [\\]z::-        subtract xmin and ymin from x and y in the triplet
                    (in the latest CJam code this is simply ".-")
$                   sort the spiral (putting the triplets in order by x then y)
_W=0=)              get the maximum (updated) x and increment it
S50*                make a string of 50 spaces
a*                  put it in an array and repeat it xmax+1 times
                    this is the initial matrix of spaces
\                   swap with the spiral
{…}/                for each triplet in the spiral
    ~               dump the 3 items (x y char) on the stack
    3$3$=           copy the matrix and x, and get the x'th row
    \t              swap with the character and put that character in the y'th position
    t               put the modified row in the x'th position in the matrix
N*                  join the matrix rows with newlines

Python 2, 290 289
It's probably really bad, but I tried :D
The output contains trailing spaces, but that is not forbidden in the spec.
Update: saved 1 byte with changing \n  to ;.
m=x=y=c=0
l,f=1,[31*[' ']for t in[0]*31]
for i in[0]*input():
 k=m%4;f[14+y+(2<m<6)][14+x-(m>3)],x,y,c='|/_\\'[k],x+(k>0)*(2*(4>m)-1),y+(k!=2)*(2*(2<m<6)-1),c+1
 if(c==l)*(m%2)+(k==0)+(k==2)*(c==2*l-1+m//3):m,c,l=(m+1)%8,0,l+m//7
print'\n'.join(''.join(e[16-l*2:])for e in f if[' ']*31!=e)

Trailing spaces are fine. I tested this. Nice job!

JavaScript (ES6) 257 288 321
Edit Steps merged.
Edit Golfed code fiddling to cut some more char
Build the output iteratively into the r array, keeping track of current x and y position and current direction. When the x or y position is < 0 the whole r array is readjusted.
Main variables:

r result array or rows
x,y current position.
s current direction (0..7) (or current state)
d current symbol to draw (0..3) -> '|\_/'
l runnig position on the current sequence (down to 0)
w current spiral radius (more or less)

F=n=>
  (w=>{
    for(r=b=[],s=y=x=d=0;n--;
      d&&--l||((s=s+1&7,d=s&3)?l=d-2?w:s/2-2+w+w:w+=!s))
      s>0&s<4?++x:s>4?x?--x:r=r.map(v=>' '+v):b+='  ',
      q=r[s>2&s<6?++y:y]||b,
      r[y]=(q+b).slice(0,x)+'|/_\\'[d]+q.slice(x+1),
      s<2|s>6?y?--y:r=[,...r]:x+=!d*2,x-=!d
  })(1)||r.join('\n')

Ungolfed
F=n=>{
  var r=[], s,x,y,d,w,l, q
  for(l=w=1, s=x=y=d=0; n--;)
  {
    if (s>2 && s<6) ++y; // right side, inc y before drawing

    if (x < 0) // too left, adjust
    {
      r = r.map(v=>' '+v) // shift all to right
      ++x; // move current position to right
    }
    if (y < 0) // too up
    {
      r = [q='',...r] // shift all to bottom
      ++y; // move current position to bottom
    }
    q = r[y] || ''; // current row, if undefined convert to empty string
    r[y] = (q+' '.repeat(x)).slice(0,x) + '|/_\\'[d] + q.slice(x+1); // add current symbol in the x column

    if (s<2 || s>6) --y; // left side, dec y after drawing

    if (s>0 && s<4) // always change x after drawing
      ++x;
    else if (s > 4)
      --x;

    --l; // decrement current run
    if (l == 0) // if 0, need to change direction
    {
      s = (s+1) % 8; // change direction
      d = s % 4; // change symbol
      if (d == 0)
      {
        // vertical direction, adjust x and if at 0 increase radius
        l = 1 // always 1 vertical step
        if (s == 0)
          ++x, ++w
        else
          --x
      }
      else
      {
        if (d != 2)
        {
          l = w; // diaagonal length is always w
        }
        else if (s == 2)
        {
          l = w+w-1 // top is radius * 2 -1
        }
        else
        {
          l = w+w+1 // bottom is radius * 2 +1
        }
      }
    }
  }
  return r.join('\n')
}

Test In Firefox/FireBug console (or JSFiddle thx @Rainbolt)
;[1, 2, 10, 20, 155, 278].forEach(x=>console.log(F(x)))

Output
|

/
|

   _
  / \
  | |
\___/

  ___
 / _ \
/ / \ \
| | | |
\___/ /

      ___________
     / _________ \
    / / _______ \ \
   / / / _____ \ \ \
  / / / / ___ \ \ \ \
 / / / / / _ \ \ \ \ \
/ / / / / / \ \ \ \ \ \
| | | | | | | | | | | |
\ \ \ \ \___/ / / / /
 \ \ \ \_____/ / / /
  \ \ \_______/ / /
   \ \_________/ /
    \___________/

        _______________
       / _____________ \
      / / ___________ \ \
     / / / _________ \ \ \
    / / / / _______ \ \ \ \
   / / / / / _____ \ \ \ \ \
  / / / / / / ___ \ \ \ \ \ \
 / / / / / / / _ \ \ \ \ \ \ \
/ / / / / / / / \ \ \ \ \ \ \ \
| | | | | | | | | | | | | | | |
\ \ \ \ \ \ \___/ / / / / / / /
 \ \ \ \ \ \_____/ / / / / / /
  \ \ \ \ \_______/ / / / / /
   \ \ \ \_________/ / / / /
    \ \ \___________/ / / /
     \ \_____________/ / /
      \_______________/ /

I tested this and it works. Here's a jsfiddle that shows your answer working. Feel free to incorporate it into your answer.

Pyth, 166 165
I just translated my Python answer to Pyth, with my not-great Pyth skills. The resulting vomit is below.
Jm*31]d*31dK0=G0=H0=Y1VQ X@J++14H&<2K<K6+14-G<3K@"|/_\\"%K4~G*<0%K4-*2>4K1~H*n2%K4-*2&<2K>6K1~Z1I||&qZY%K2!%K4&q2%K4qZ+-*2Y1/K3~Y/K7=K%+1K8=Z0;jbmj>d-16*2Ykfn*31]dTJ