text:
Draw ASCII Playing Cards
Consider these 15 ASCII playing card patterns (ace through Joker, and the back side), where X is a placeholder for the suit symbol: (they look better with less line spacing)
 -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------
|AX           | |2X           | |3X           | |4X           | |5X           | |6X           | |7X           | |8X           | |9X           | |10X          | |JX           | |QX           | |KX           | |J            | |* * * * * * *|
|   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |O  -------   | | * * * * * * |
|  |       |  | |  |       |  | |  |       |  | |  |X     X|  | |  |X     X|  | |  |X     X|  | |  |X     X|  | |  |X     X|  | |  |X     X|  | |  |X     X|  | |  |X      |  | |  |X      |  | |  |X      |  | |K |       |  | |* * * * * * *|
|  |       |  | |  |   X   |  | |  |   X   |  | |  |       |  | |  |       |  | |  |       |  | |  |   X   |  | |  |   X   |  | |  |       |  | |  |   X   |  | |  |       |  | |  |       |  | |  |       |  | |E | J     |  | | * * * * * * |
|  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |X     X|  | |  |X     X|  | |  |       |  | |  |       |  | |  |       |  | |R |  O    |  | |* * * * * * *|
|  |   X   |  | |  |       |  | |  |   X   |  | |  |       |  | |  |   X   |  | |  |X     X|  | |  |X     X|  | |  |X     X|  | |  |   X   |  | |  |       |  | |  |   J   |  | |  |   Q   |  | |  |   K   |  | |  |   K   |  | | * * * * * * |
|  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |X     X|  | |  |X     X|  | |  |       |  | |  |       |  | |  |       |  | |  |    E  | J| |* * * * * * *|
|  |       |  | |  |   X   |  | |  |   X   |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |   X   |  | |  |       |  | |  |   X   |  | |  |       |  | |  |       |  | |  |       |  | |  |     R | O| | * * * * * * |
|  |       |  | |  |       |  | |  |       |  | |  |X     X|  | |  |X     X|  | |  |X     X|  | |  |X     X|  | |  |X     X|  | |  |X     X|  | |  |X     X|  | |  |      X|  | |  |      X|  | |  |      X|  | |  |       | K| |* * * * * * *|
|   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------  E| | * * * * * * |
|           XA| |           X2| |           X3| |           X4| |           X5| |           X6| |           X7| |           X8| |           X9| |          X10| |           XJ| |           XQ| |           XK| |            R| |* * * * * * *|
 -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------

Write a program that takes in a string denoting a space separated sequence of cards using...

A 2 3 4 5 6 7 8 9 10 J Q K followed by one of C D H S (for clubs, diamonds, hearts, and spades) for the 52 standard cards.
A single R for a Joker.
A single B for the back side (a face down card).

So the string B AS KH 10C R JD denotes a face down card, followed by an ace of spades, followed by a king of hearts, followed by a ten of clubs, followed by a Joker, followed by a jack of diamonds.
Your program needs to print the corresponding ASCII playing cards to stdout, replacingX with the appropriate suit symbol.
For example, the output for B AS KH 10C R JD would be
 -------------   -------------   -------------   -------------   -------------   -------------
|* * * * * * *| |AS           | |KH           | |10C          | |J            | |JD           |
| * * * * * * | |   -------   | |   -------   | |   -------   | |O  -------   | |   -------   |
|* * * * * * *| |  |       |  | |  |H      |  | |  |C     C|  | |K |       |  | |  |D      |  |
| * * * * * * | |  |       |  | |  |       |  | |  |   C   |  | |E | J     |  | |  |       |  |
|* * * * * * *| |  |       |  | |  |       |  | |  |C     C|  | |R |  O    |  | |  |       |  |
| * * * * * * | |  |   S   |  | |  |   K   |  | |  |       |  | |  |   K   |  | |  |   J   |  |
|* * * * * * *| |  |       |  | |  |       |  | |  |C     C|  | |  |    E  | J| |  |       |  |
| * * * * * * | |  |       |  | |  |       |  | |  |   C   |  | |  |     R | O| |  |       |  |
|* * * * * * *| |  |       |  | |  |      H|  | |  |C     C|  | |  |       | K| |  |      D|  |
| * * * * * * | |   -------   | |   -------   | |   -------   | |   -------  E| |   -------   |
|* * * * * * *| |           SA| |           HK| |          C10| |            R| |           DJ|
 -------------   -------------   -------------   -------------   -------------   -------------

You can take the input from stdin or write a function that takes a string.
The submission with the shortest number of characters wins.
Bonus: Subtract 30 from your character count if you use the black Unicode suit symbols ♣ ♦ ♥ ♠ instead of C D H S in your output. (The input always uses C D H S.)
Notes

There may be more than 54 cards in the input string and there may be duplicates of any card.
There should be no output if the input is the empty string.
There should be no trailing spaces besides (optionally) the two that make up the right corners of the last card.
You may assume the input is valid.
Update: The lower right label on standard cards has been reversed so the value is in the corner. The lower right Joker label hasn't changed.

Can we assume the input string is valid ?

Should the lower-right Joker be upside down?

@VisualMelon I tried that but it looks funny. It will stay upright.

May I suggest a -20 score if someone prints the lower right label (be it JOKER or NX) using the upside down symbols equivalent to the English alphabets. Example : S∀, ᴚƎʞOſ etc.

@Optimizer I would do that if there were designated upsidedown characters for what I need but I don't think there are and I don't want it all wonky.

Should the lower-right 10X be X01, rather than X10? This is what I would figure from the pictures on Wikipedia

@VisualMelon I know that realistically half of the labels would be upside down, but since there aren't upside down characters for that I'm ignoring that fact (besides that I wanted the values in the corner).

If you're only going to subtract 10 points for properly Unicoding the symbols, it's never going to be worth it because you need more than that just to write them (6 characters per symbol, 24 overall). Even if you got a unicode-compliant language, the unicode symbols are in the reverse order from your input when alphabetical. I think only something like CJAM, APL or Golfscript would be able to do that.

@NateKerkhofs Good points. The bonus has been changed from 10 to 30.

JavaScript (E6) 542 (572 - bonus 30) 553 564 576
3 kinds of shapes:

Back and Joker: more or less literal
JQK: mark at topleft and rightbottom, inner frame and 3 kind of rows inside, always the same structure
A...10: mark at topleft and rightbottom, inner frame with 3 kind of rows inside, variable with the numeric value. Taken care of with lookup using array and q variable

The z string (compressed) contains the basic building blocks for

numeric cards - 3 blocks, 7 chars each
joker - 11 blocks, 13 char each, used simply in sequence

Bonus note The code for winning the 30 points bonus is 29 chars.
F=c=>(
  p='|',b=' ',d=b+b,t=d+b,
  S='substr',
  z="9J2J4J55O102K |6|1E | J4|1R |1O3|3|2K2|3|3E1| J1|4R | O1|6| K201E55R".replace(/\d/g,n=>n++?b.repeat(n):l='-------'),
  i=7,
  console.log([c.split(b).map(c=>
    m<d
      ?b+l+l[S](1)+b
      :p+(c=='B'
        ?'* '.repeat(i)[S](i,13)
        :c=='R'
          ?z[S](i,13)
          :(
             [,h,k]=c.match(/(.+)(.)/),
             k='♣♦♥♠'['CDHS'.search(k)], //comment to avoid the unicode symbols
             n=h-1|0,
             s=t+t+t+(n>8?b:d),
             m-7
              ?m-8
                ?m-9
                  ?d+p+(h>'A'
                     ?-m?m-6?m-3?t+b+t:t+h+t:t+t+k:k+t+t
                     :z[S](([64,1028,1092,8194,8258,8322,8326,9350,8802,9766][n]>>m*2&3)*7,7).replace(/J/g,k)
                   )+p+d
                  :t+l+t
                :s+k+h
              :h+k+s
            )
       )+p
    ).join(b,i+=13)
  for(m of ' 79012345698 ')].join('\n'))
)

Test In FireFox/FireBug console
F('10C JD QH KS AC B R')

F('2C 3D 4H 5S 6C 7D 8H 9S')

Output
 -------------   -------------   -------------   -------------   -------------   -------------   -------------
|10♣          | |J♦           | |Q♥           | |K♠           | |A♣           | |* * * * * * *| |J            |
|   -------   | |   -------   | |   -------   | |   -------   | |   -------   | | * * * * * * | |O  -------   |
|  |♣     ♣|  | |  |♦      |  | |  |♥      |  | |  |♠      |  | |  |       |  | |* * * * * * *| |K |       |  |
|  |   ♣   |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | | * * * * * * | |E | J     |  |
|  |♣     ♣|  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |* * * * * * *| |R |  O    |  |
|  |       |  | |  |   J   |  | |  |   Q   |  | |  |   K   |  | |  |   ♣   |  | | * * * * * * | |  |   K   |  |
|  |♣     ♣|  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |* * * * * * *| |  |    E  | J|
|  |   ♣   |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | | * * * * * * | |  |     R | O|
|  |♣     ♣|  | |  |      ♦|  | |  |      ♥|  | |  |      ♠|  | |  |       |  | |* * * * * * *| |  |       | K|
|   -------   | |   -------   | |   -------   | |   -------   | |   -------   | | * * * * * * | |   -------  E|
|          ♣10| |           ♦J| |           ♥Q| |           ♠K| |           ♣A| |* * * * * * *| |            R|
 -------------   -------------   -------------   -------------   -------------   -------------   -------------

 -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------
|2♣           | |3♦           | |4♥           | |5♠           | |6♣           | |7♦           | |8♥           | |9♠           |
|   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   |
|  |       |  | |  |       |  | |  |♥     ♥|  | |  |♠     ♠|  | |  |♣     ♣|  | |  |♦     ♦|  | |  |♥     ♥|  | |  |♠     ♠|  |
|  |   ♣   |  | |  |   ♦   |  | |  |       |  | |  |       |  | |  |       |  | |  |   ♦   |  | |  |   ♥   |  | |  |       |  |
|  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |♠     ♠|  |
|  |       |  | |  |   ♦   |  | |  |       |  | |  |   ♠   |  | |  |♣     ♣|  | |  |♦     ♦|  | |  |♥     ♥|  | |  |   ♠   |  |
|  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |♠     ♠|  |
|  |   ♣   |  | |  |   ♦   |  | |  |       |  | |  |       |  | |  |       |  | |  |       |  | |  |   ♥   |  | |  |       |  |
|  |       |  | |  |       |  | |  |♥     ♥|  | |  |♠     ♠|  | |  |♣     ♣|  | |  |♦     ♦|  | |  |♥     ♥|  | |  |♠     ♠|  |
|   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   | |   -------   |
|           ♣2| |           ♦3| |           ♥4| |           ♠5| |           ♣6| |           ♦7| |           ♥8| |           ♠9|
 -------------   -------------   -------------   -------------   -------------   -------------   -------------   -------------

Not golfed code
F=c=>
{
  p='|',b=' ',d=b+b,t=d+b;
  l='------';
  z="9X2X4XJ55O10-2K |6|1E | J4|1R |1O3|3|2K2|3|3E1| J1|4R | O1|6| K20-1E55R".replace(/\d/g,n=>-n?b.repeat(-~n):l);
  c=c.split(b);
  for(o=i=''; c[0]&&i<13; i++)
  {
    o+=c.map(c => {
      if (i==0 || i==12) r=' -'+l+l+b;
      else
      {
        if (c=='B') r=' *'.repeat(7).substr(i&1,13);
        else if (c=='R') r=z.substr(i*13+8,13);
        else {
          [,h,k]=c.match(/(.+)(.)/),n=h-1|0,
          k='♣♦♥♠'[{C:0,D:1,H:2,S:3}[k]],
          r=t+t+t+(n>8?b:d);
          if(i==1)r=h+k+r;
          else if(i==11)r+=k+h;
          else if(i==2||i==10)r=t+'-'+l+t;
          else {
            if (h>'A')
            {
              if(i==3)r=k+t+t;
              else if(i==9)r=t+t+k;
              else if(i==6)r=t+h+t;
              else r=t+b+t
            }
            else
            {
              q=[64,1028,1092,8194,8258,8322,8326,9350,8802,9766][n]>>(i+i-6)&3,
              r=z.substr(q*7,7).replace(/X/g,k)
            }
            r=d+p+r+p+d
          }
        }
        r=p+r+p
      }
      return r
    }).join(' ')+'\n'
  }
  console.log(o);
}

I think you swapped hearts and diamonds (in your example run anyway, I haven't been able to find the error in your code...).

@FryAmTheEggman thanks, fixed in golfed code and examples

great code! You can reduce your char count with this tool: http://xem.github.io/obfuscatweet/ (it only accepts ASCII though, so you have to escape the unicode chars before packing)

(Your final result will then be around 328!)

@xem The char count is low (337) but the byte count is high(1213) https://mothereff.in/byte-counter. Unless specified, you have to count bytes in code golf.

@edc65, it's specified "The submission with the shortest number of characters wins." ;)

C# - 906
Rather large and simple C# program that takes command-line input and outputs to standard output. There is probably a lot that can still be golfed, I've spotted a few boring bytes while writing this, but that will have to wait. I don't think I will be going for the Unicode suit character bonus.
Golfed code:
class P{static void Main(string[]A){int O,i=0,L,n;for(;i<13;i++){var k="";foreach(var a in A){var R=new char[208];System.Action<int,int,string,int>P=(s,l,g,w)=>{for(O=0;O<l;s+=O%w<1?17-w:1)R[s]=g[O++%g.Length];};P(0,208," ",16);P(1,13,"-",13);P(193,13,"-",13);P(16,11,"|",1);P(30,11,"|",1);if(a=="B")P(17,143,"* ",13);else{P(36,7,"-",7);P(164,7,"-",7);P(51,7,"|",1);P(59,7,"|",1);if(a=="R"){P(17,5,"JOKER",1);P(125,5,"JOKER",1);P(69,25,"J     O     K     E     R",5);}else{L=a.Length;var S=a.Substring(L-1);var v=a.Substring(0,L-1);P(17,L,a,L);P(190-L,L,S+v,L);if(int.TryParse(v,out n)){var f=new string[]{S="HEHI",S+"HG",S="EDKDEJKJ",S+"HG",v=S+"EGKG",v+="HE",v+"HI",(S+="EFEHKFKH")+"HG",S+"HEHI",}[n-2];for(O=0;O<f.Length;)R[f[O++]+f[O++]*16-1105]=a[L-1];}else{if(v=="A"){P(103,1,S,1);}else{P(52,1,S,1);P(154,1,S,1);P(103,1,v,1);}}}}for(O=0;O<16;)k+=R[i*16+O++];}System.Console.WriteLine(k.TrimEnd());}}}

Example output for cardGolf.exe 7H QH 3S B R
 -------------   -------------   -------------   -------------   -------------
|7H           | |QH           | |3S           | |* * * * * * *| |J            |
|   -------   | |   -------   | |   -------   | | * * * * * * | |O  -------   |
|  |H     H|  | |  |H      |  | |  |       |  | |* * * * * * *| |K |       |  |
|  |   H   |  | |  |       |  | |  |   S   |  | | * * * * * * | |E | J     |  |
|  |       |  | |  |       |  | |  |       |  | |* * * * * * *| |R |  O    |  |
|  |H     H|  | |  |   Q   |  | |  |   S   |  | | * * * * * * | |  |   K   |  |
|  |       |  | |  |       |  | |  |       |  | |* * * * * * *| |  |    E  | J|
|  |       |  | |  |       |  | |  |   S   |  | | * * * * * * | |  |     R | O|
|  |H     H|  | |  |      H|  | |  |       |  | |* * * * * * *| |  |       | K|
|   -------   | |   -------   | |   -------   | | * * * * * * | |   -------  E|
|           H7| |           HQ| |           S3| |* * * * * * *| |            R|
 -------------   -------------   -------------   -------------   -------------

Most of the rendering is done by the P anonymous method, which takes a position, length, string, and width, and renders a rectangle of the string end on end. For example, the back of the card is just "* " repeated. The T anonymous method is a modified version of one I used for a previous task, which renders lots of rectangles. It is, however, rather bulky, and would only allow me to render the borders and background in fewer bytes, which probably isn't worth it. A striped down version of T is W which renders cells rather than rectangles, and also isn't used, but an inlined version of it is used to render cards of value 2 through 10. Note that unused code was removed for the byte count, I'm leaving it in because I may end up using it, and I do use them for testing.
The program simply loops through each line of output (13 of them) and then renders each card in turn, and then extracts 1 slice from it, so each card is rendered in it's entirety 13 times. For the purpose of spacing them, each card is treated as a 16 by 13 block, and I trim each line of output to remove trailing spaces (the corner spaces are removed).
Formatted code, with comments and concept/testing code:
class P
{
    static void Main(string[]A)
    {
        int O,J,i=0,L,n,r,z;

        for(;i<13;i++)
        {
            var k="";
            foreach(var a in A)
            {
                // got card a and line i

                var R=new char[208];

                System.Action<int,int,string,int>P=(s,l,g,w)=>
                {
                    for(O=0;O<l;s+=O%w<1?17-w:1)
                        R[s]=g[O++%g.Length];
                };

                // not used
                System.Action<string>T=f=>
                {
                    f+="AAPM!";
                    for(J=64;J++<77;)
                        for(O=64;O++<80;R[z=O+J*16-1105]=f[r]=='!'?R[z]:f[r])
                            for(r=0;f[r++]>O|f[r++]>J|O>f[r++]|J>f[r++];r++);
                };

                // not used (derivative below)
                System.Action<string>W=f=>
                {
                    for(O=0;O<f.Length;)
                        R[f[O++]+f[O++]*16-1105]=f[O++];
                };

                // render

                // outer

                P(0,208," ",16); // fill
                P(1,13,"-",13); // top
                P(193,13,"-",13); // bottom
                P(16,11,"|",1); // left
                P(30,11,"|",1); // left

                //T("BBNL BANM-ABOL|AAPM ");

                if(a=="B") // back
                    P(17,143,"* ",13);
                else
                {
                    // inner

                    P(36,7,"-",7); // top
                    P(164,7,"-",7); // bottom
                    P(51,7,"|",1); // left
                    P(59,7,"|",1); // left

                    //T("EDKJ ECKK-DDLJ|");

                    // joker
                    if(a=="R")
                    {
                        P(17,5,"JOKER",1);
                        P(125,5,"JOKER",1);
                        P(69,25,"J     O     K     E     R",5);
                        //T("FEFEJGFGFOHGHGKIHIHEJIJIR");
                    }
                    else
                    {
                        L=a.Length;

                        // card
                        var S=a.Substring(L-1);
                        var v=a.Substring(0,L-1);

                        P(17,L,a,L);
                        P(190-L,L,S+v,L);

                        if(int.TryParse(v,out n))
                        {
                            // number card
                            var f=new string[]
                            {
                                S="HEHI",
                                S+"HG",
                                S="EDKDEJKJ",
                                S+"HG",
                                v=S+"EGKG",
                                v+="HE",
                                v+"HI",
                                (S+="EFEHKFKH")+"HG",
                                S+"HEHI",
                            }[n-2];
                            for(O=0;O<f.Length;)
                                R[f[O++]+f[O++]*16-1105]=a[L-1];
                        }
                        else
                        {
                            if(v=="A")
                            {
                                // ace
                                P(103,1,S,1);
                            }
                            else
                            {
                                // face card
                                P(52,1,S,1);
                                P(154,1,S,1);
                                P(103,1,v,1);
                            }
                        }
                    }
                }

                // write

                for(O=0;O<16;)
                    k+=R[i*16+O++];
            }
            System.Console.WriteLine(k.TrimEnd());
        }
    }
}

PowerShell, score 442 = (509 495 472 bytes = (156 script + 316 archive) - 30 bonus)
param($s)tar xOf t|%{$l=$_
($s-split'1| '-ne''|%{($l|% s*g(14*('A234567890JQKRB'|% i*f $_[0]))15)-replace'X','♣♦♥♠'[('CDHS'|% i*f $_[1])]})-join' '}

Try it online!
Unrolled:
# # the tar archive t should be in default folder
param($s)
tar xOf t|%{ $line=$_
    ($s-split'1| '-ne''|%{
        $pos = 14*('A234567890JQKRB'|% indexOf $_[0])
        $x=$line|% SubString $pos 15

        $suit = 'CDHS'|% indexOf $_[1]
        $x-replace'X','♣♦♥♠'[$suit]
    })-join' '                                          # implicit output
}

Powershell script to create the tar archive t (see TIO):
(
' ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ',
'|AX           |2X           |3X           |4X           |5X           |6X           |7X           |8X           |9X           |10X          |JX           |QX           |KX           |J            |* * * * * * *|',
'|   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |O  -------   | * * * * * * |',
'|  |       |  |  |       |  |  |       |  |  |X     X|  |  |X     X|  |  |X     X|  |  |X     X|  |  |X     X|  |  |X     X|  |  |X     X|  |  |X      |  |  |X      |  |  |X      |  |K |       |  |* * * * * * *|',
'|  |       |  |  |   X   |  |  |   X   |  |  |       |  |  |       |  |  |       |  |  |   X   |  |  |   X   |  |  |       |  |  |   X   |  |  |       |  |  |       |  |  |       |  |E | J     |  | * * * * * * |',
'|  |       |  |  |       |  |  |       |  |  |       |  |  |       |  |  |       |  |  |       |  |  |       |  |  |X     X|  |  |X     X|  |  |       |  |  |       |  |  |       |  |R |  O    |  |* * * * * * *|',
'|  |   X   |  |  |       |  |  |   X   |  |  |       |  |  |   X   |  |  |X     X|  |  |X     X|  |  |X     X|  |  |   X   |  |  |       |  |  |   J   |  |  |   Q   |  |  |   K   |  |  |   K   |  | * * * * * * |',
'|  |       |  |  |       |  |  |       |  |  |       |  |  |       |  |  |       |  |  |       |  |  |       |  |  |X     X|  |  |X     X|  |  |       |  |  |       |  |  |       |  |  |    E  | J|* * * * * * *|',
'|  |       |  |  |   X   |  |  |   X   |  |  |       |  |  |       |  |  |       |  |  |       |  |  |   X   |  |  |       |  |  |   X   |  |  |       |  |  |       |  |  |       |  |  |     R | O| * * * * * * |',
'|  |       |  |  |       |  |  |       |  |  |X     X|  |  |X     X|  |  |X     X|  |  |X     X|  |  |X     X|  |  |X     X|  |  |X     X|  |  |      X|  |  |      X|  |  |      X|  |  |       | K|* * * * * * *|',
'|   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------   |   -------  E| * * * * * * |',
'|           XA|           X2|           X3|           X4|           X5|           X6|           X7|           X8|           X9|          X10|           XJ|           XQ|           XK|            R|* * * * * * *|',
' ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- ------------- '
) | Set-Content f -Force
tar zcf t f -o
Get-ChildItem t # output info about archive size


text:
Tension on a Graph, Part I: A Wavy String
Let's plot a function f(x) = sin(πx) + 0.5 sin(3πx) over the domain [-3,3]. We can interpret this as a loose string lying on a board. Now let's drive n nails into the board at positions (x1, y1) to (xn, yn), where the xi ∈ (-3,3) and yi ∈ [-1,1]. Imagine that there are two eyelets at the end of the string, that is at positions (-3,0) and (3,0). We can now take the ends of string and pull the through the eyelets until the string is taut. This will deform our graph into a piecewise linear function.
Some pictures might help. Take 8 nails at (-2.8, -0.7), (-2.5, -0.9), (-1.2, .2), (-0.5, .8), (0.5, .4), (1.2, -0.9), (1.5, -0.6), (1.8, -0.8). The following three plots show the process described above:

For larger version: Right-click --> Open in new tab
And here is an animation of the string tightening if you have some difficulty visualising it:

The Challenge
Given a list of "nails" (which is not necessarily sorted), plot those nails and the taut string if it starts from the shape of the above function f.
You may write a program or function and take input via STDIN, ARGV or function argument. You can either display the result on the screen or save an image to a file.
If the result is rasterised, it needs to be at least 300 pixels wide and 100 pixels tall. The coordinate range from (-3,-1.1) to (3,1.1) must cover at least 75% of the horizontal and vertical extent of the image. The length scales of x and y do not have to be the same. You need to show the nails (using at least 3x3 pixels) and the string (at least 1 pixel wide). You may or may not include the axes.
Colours are your choice, but you need at least two distinguishable colours: one for the background and one for the nails and the string (those may have different colours though).
You may assume that all nails are at least 10-5 units away from f (so that you don't need to worry about floating-point inaccuracy).
This is code golf, so the shortest answer (in bytes) wins.
More Examples
Here are two more (simpler) examples:
{{-2.5, 1}, {-1.5, -1}, {-0.5, 1}, {0.5, -1}, {1.5, 1}, {2.5, -1}}

(The string coincides with the x-axis.)
{{-2.7, -0.5}, {-2.3, -0.5}, {-1.7, 0.5}, {-1.3, 0.5}, {-0.7, -0.5}, {-0.3, -0.5}, {0.5, 1}, {1.5, -1}, {2.5, 1}}

Want another Challenge?
Here is Part II!

Can we assume that the nails are sorted from left to right?

@Ell Ah, good catch. Since I haven't specified it to begin with, no. I'll clarify that.

Python + Pycairo, 727 708 608, + PyLab, 383
from pylab import*
def f(N):
 def P(u,w,N):
    T=lambda v,p:(C(v-u,p-u)>0)==(C(w-v,p-v)>0)==(C(u-w,p-w)>0);M=[(i,n)for i,n in enumerate(N)if T(V([n[0],sin(pi*n[0])+sin(3*pi*n[0])/2]),n)]
    if M:i,n=max(M,key=lambda n:C(n[1]-u,w-u)**2);M=P(u,n,N[:i])+[n]+P(n,w,N[i+1:])
    return M
 V=array;C=cross;a=V([3,0]);plot(*zip(*([-a]+P(-a,a,map(V,sorted(N)))+[a])));N and scatter(*zip(*N));show()

Example
f([(-2.8,-0.7),(-2.5,-0.9),(-1.2,0.2),(-0.5,0.8),(0.5,0.4),(1.2,-0.9),(1.5, -0.6),(1.8, -0.8)])

How it works

 Suppose we know that the taut string passes through two points A and
 B (we can always start with  A = (-3, 0) and B = (3, 0).) As we pull the string, it "wants" to take the shortest path possible between
 A and B, that is, ideally, the segment AB. However, if there are any nails in the area bounded by the function (sin πx + ...)
 and AB, then at least one of them must block the string. In
 particular, the nail(s) farthest away from AB within the said area
 must block the string. Hence, if C is this nail, we know that the
 taut string must pass through C, in addition to A and B. We can
 now repeat the process for the segments AC and CB, and continue in
 this fashion until eventually there are no more intervening nails.

 This is a binary divide-and-conquer algorithm with a linear scan in
 each step, so it has a best-case complexity of O(n log n) and
 worst-case complexity of O(n2).

It errors if the list of points is empty. But other than that mine is obviously hopeless!

@feersum Good catch. Fixed.

Python + pylab, 576 bytes
Algorithm:

 I interpreted the problem as finding the shortest path from (-3, 0) to (3, 0) such that a vertical line segment connecting a point on the path to a point on f(x) never crosses a nail.

 At each x where exists at least one nail, find the least upper bound
 and greatest lower bound given by the nails at that x. Consider the
 points given by these bounds plus the starting and ending points to be
 the vertices on a graph. Add an edge with weight given by the
 Euclidean distance between two vertices iff the line segment between
 them falls within the upper and lower bounds for each intervening x
 coordinate. Find the shortest path on this graph.

Example with 27 random points:
(-0.367534, -0.722751), (-0.710649, -0.701412), (1.593101, -0.484983), (1.771199, 0.681435), (-1.878764, -0.491436), (-0.061414, 0.628570), (-0.326483, -0.512950), (0.877878, 0.858527), (1.256189, -0.300032), (1.528120, -0.606809), (-1.343850, -0.497832), (1.078216, 0.232089), (0.930588, -0.053422), (-2.024330, -0.296681), (-2.286014, 0.661657), (-0.009816, 0.170528), (2.758464, 0.099447), (-0.957686, 0.834387), (0.511607, -0.428322), (-1.657128, 0.514400), (1.507602, 0.507458), (-1.469429, -0.239108), (0.035742, 0.135643), (1.194460, -0.848291), (2.345420, -0.892100), (2.755749, 0.061595), (0.283293, 0.558334),

Golfed
What appears as several spaces of indentation in the for j in R(i&~1) loop should actually be a tab.
from pylab import*
P=((3,0),(-3,0))+input()
X=sorted(set(zip(*P)[0]))
l=len(X)*2
if l>4:scatter(*zip(*P[2:]))
f=lambda x:sin(pi*x)+sin(3*pi*x)/2
B=[[max([-9]+[p[1]for p in P if x==p[0]and p[1]<f(x)]),min([9]+[p[1]for p in P if x==p[0]and p[1]>f(x)])]for x in X]
b=zeros(l);b[2:]=inf
v=list(b)
R=range
for i in R(l):
 for j in R(i&~1):
    A=B[j/2][j&1];D,d=B[i/2][i&1]-A,X[i/2]-X[j/2];K=1;c=b[j]+norm((d,D))
    for k in R(j/2+1,i/2):C=A+D/d*(X[k]-X[j/2]);K&=C<B[k][1];K&=C>B[k][0]
    if(c<b[i])&K:b[i]=c;v[i]=j,(X[j/2],A)
l-=2
s=P[:1]
while l/2:l,p=v[l];s+=(p,)
plot(*zip(*s))
show()

Ungolfed
from pylab import*
P = input()
Xn,Yn = zip(*P)
X = set(Xn+(3,-3))
f = lambda x:sin(pi*x)+sin(3*pi*x)/2
ylb = {x: max([-9]+[p[1] for p in P if p[0] == x and p[1] < f(x)]) for x in X}
yub = {x: min([9]+[p[1] for p in P if p[0] == x and p[1] > f(x)]) for x in X}
ylb[-3] = yub[3] = ylb[3] = 0
X = sorted(X)
l = len(X)
best = zeros((l,2))
best[1:] = inf
prev = [ [0,0] for i in range(l) ]
for i in range(l): # calculate min path to X[i] lb or ub
  for ib in 0,1:
    for j in range(i): # point to come from
      for jb in 0,1:
          Y2, Y1 = (ylb, yub)[ib][X[i]], (ylb, yub)[jb][X[j]]
          dy,dx = Y2 - Y1, X[i] - X[j]
          if all([Y1 + dy/dx*(x - X[j]) < yub[x] and Y1 + dy/dx*(x - X[j]) > ylb[x] for x in X[j+1:i]]):
             c = best[j][jb] + (dy**2+dx**2)**.5
             if c < best[i][ib]:
                 best[i][ib] = c
                 prev[i][ib] = j, jb, (X[j], Y1)
j, jb = l-1,0
pts = [(3,0)]
while j:
    j, jb, p = prev[j][jb]
    pts += [p]
plot(*zip(*pts))
scatter(Xn,Yn)
show()

PyLab was definitely a smarter choice :)

source: Stack Exchange

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

sort: votes


text:
Line numbering - implement nl
Your task is to implement a program similar to the nl command-line tool from the GNU core utilities.
Standard loopholes are banned.
You may not use any built-in or external function, program or utility for numbering the lines of a file or string, such as nl itself or the = command in GNU sed.
Specification
Input
The program accepts filenames as arguments. Your code does not have to be cross-platform; the filename format of the OS running the code should be used, i.e. if you happen to be on Windows, the directory separator can be \ or /.
You must be able to take 64 input files, including - if it is specified. If over 64 are given, only handle the first 64.
In the list of filenames, - represents standard input.
If filenames are given, read from the files in the order that they are given and concatenate their contents, inserting a new line between each one and at the end. If you cannot read from one or more of the filenames (because the file does not exist or you do not have read permissions for it), ignore them. If all filenames specified are invalid, output nothing.
If no filenames are given, read from standard input. Only read from standard input if no filenames are given or if - is given.
Output
The program will output, to standard output, the input with lines numbered thus (You may assume that the input has \n, \r\n or \r line endings; pick whichever is convenient for you, but specify which one):
<5 spaces>1<tab><content of line 1 of input>
<5 spaces>2<tab><content of line 2 of input>
...
<4 spaces>10<tab><content of line 10 of input>
...
<3 spaces>100<tab><content of line 100 of input>
...
...

6 characters of space are allocated for the line number, and it is inserted at the end of these characters; the rest become spaces (e.g. 1 will have 5 leading spaces, 22 will have 4 leading spaces, ...). If the input is sufficiently long, you will eventually run out of space for the line number, at line 999999. You must not output anything after line 999999.
If the input is empty, output nothing.
Exit status
The lower numbers take priority: if errors 1 and 2 were encountered, exit with status 1.
Exit with status 0 if the input was successfully received, and the lines successfully numbered and output.
Exit with status 1 if one or more of the files specified on the command line were not found or could not be read from.
Exit with status 2 if too many files (more than 64) were given.
Exit with status 3 if the input was too long (more than 999999 lines).\
Scoring
This is code-golf - shortest program wins!
I may add bonuses later for implementing certain options that nl has. There are no bonuses at the moment.

Is the line-numbering continuous or short it "reset" itself for each individual file?

@britishtea It is continuous

So is it necessary to use node if we want to submit something in js? Or can we use function args or prompt() to emulate program args and stdin?

Binary files? Encoding? Unicode markers?

Bash, 121
s=$[2*($#>64)]
for f in "$@";{ [ -f $f ]||s=1;}
((s))&&exit $s
awk '{if(NR>=10**6){exit 3}printf("%6d\t%s\n",NR,$0)}' $@

You can make your if expressions quite a bit shorter if you use arithmetic expressions, e.g. (($#>64))&&s=2

@DigitalTrauma I learned a thing!

You can replace s=0;(($#>64))&&s=2 with s=$[2*($#>64)], (($s==0))|| with ((s))&& and the if statement with [ -f "$f" ]||s=1.

http://codegolf.stackexchange.com/a/25802/11259

awk will also concatenate if passed multiple files, so this officially counts as a useless use of cat ;-).  Instead I think this will work: awk '...' $@

You may be able to use the fact that when undefined variables appear in arithmetic expansions, they will expand to 0, to get rid of the s=0 line.

@Sammitch Change your third line to for f in "$@";{ [ -f "$f" ]||s=1;} - saves a lot of chars. I think the quotes around $f are necessary in case your filename has spaces in it

@Sammitch I've tested this, but it doesn't seem to handle - for STDIN correctly

The spec says you should handle the first 64 inputs if given more than 64, rather than just giving up at the beginning. I think it also suggests that you should output all the readable files if only some of them are readable.

Ruby, 195
o,l=$*[64]?[2]:[],999999
($*==[]?[?-]:$*).each{|n|f=n==?-?STDIN: open(n)rescue o<<1&&next
s=f.read.lines
s[l]?o<<3:1
puts s[0..l].map.with_index(1){|l,i|i.to_s.rjust(6)+?\t+l}}
exit !o[0]?0:o.min

I think STDIN is aliased to $<.

It's an alias for ARGF, which will read from the rest of the files given as arguments as well. I think this can be golfed down further using ARGF somehow (it even seems to recognize "-" as being stdin).

britishteanl:4:in block in <main>': undefined method []'   for #Enumerator:0x000006002980c8 (NoMethodError)
from britishteanl:2:in each'           from britishteanl:2:in ' - what's wrong? I ran it as ruby britishteanl folder/filename

I suspect it's a difference in Ruby version. I've run the sample on both Ruby 2.0.0 and Ruby 2.1.2 without problems. What version are you using?

python 173
import os,sys
c=0
l=1
for f in sys.argv[1:]:
    if c>64:exit(2)
    if not os.path.isfile(f):exit(1)
    c+=1
    for x in open(f):
        if l>=10**6:exit(3)
        print '%6d\t%s'%(l,x),;l+=1

I think your code is currently missing the - for sys.stdin. A possible solution might be something like fh=sys.stdin if f=='-' else open(f) and then go with x=fh.readline()?! Unfortunately it does not make it any shorter though. :)

J (162)
exit(((2*64<#)[exit@3:`(stdout@(,&LF)@;@(,&TAB@(6&":)&.>@>:@i.@#,&.>]))@.(1e6>#)@(<;.2)@(1!:1)@(<`3:@.('-'-:]))&.>@;@{.@(_64&(<\))) ::1:)]`(]&<&'-')@.(0=#)2}.ARGV

Explanation:

]`(]&<&'-')@.(0=#)2}.ARGV: Get the command line arguments, and remove the first two (because those are the interpreter and the script file name). If the resulting list is empty, return ['-'] (i.e., as if the user had passed only -), otherwise return the list unchanged.
( ... ::1:): if the inner function fails, return 1, otherwise return whatever the inner function returned.
((2*64<#)[...): evaluate the inner function and throw the result away. Then, if the length of the passed list was not higher than 64, return 0, otherwise return 2.
&.>@;@{.@(_64&(<\)): get at most 64 elements from the list, and for each of them run the following function:

(1!:1)@(<`3:@.('-'-:])): if the element was -, read the contents of file descriptor 3 (stdin), otherwise read the contents of the file named by that element. If this fails (i.e. file doesn't exist), the code above will catch it and return 1.
exit@3:`(...)@.(1e6>#)@(<;.2): split the string on its line endings. If there are 1.000.000 or more lines, exit with status 3. Otherwise:

,&TAB@(6&":)&.>@>:@i.@#: generate the numbers for each line, format them in a 6-digit column, and add a TAB to the end of each string,
,&.>]: add each number to the front  of each line.
stdout@(,&LF)@;: then output the whole thing, followed by an extra LF.

exit: exit with the return value of that function

Ruby, 76 bytes
One byte for the p flag. Run with ruby -p nl.rb.
BEGIN{x=$*.size-65}
exit 2if$*.size==x
exit 3if$.>999999
$_="%6d"%$.+?\t+$_

stdin or file arguments are handled automatically by Ruby. It already exits with code 1 if a file argument doesn't exist. $. is the number of lines that have been read. $* is the command line arguments, and the files are popped off as the files are read. The p flag executes the BEGIN block and wraps the rest of the program inside a while-gets-print loop, using $_ as the input/output.

The spec says you should handle the first 64 inputs if given more than 64, rather than just giving up at the beginning.

@AndersKaseorg fixed.

Perl, 125 122 bytes
@a=@ARGV;for(@a){$i++>63&&exit 2;($_ eq '-'or-e$_)or next;@ARGV=$_;while(<>){$c>1E6-2&&exit 3;printf"%5d\t%s",++$c,$_}say}

This does not satisfy the specification regarding the 64 argument maximum and the exit status.

@AndersKaseorg Fixed!

Perl, 84 + 2 (-pl) = 86 bytes
perl -ple'BEGIN{map{-r||exit 1}@ARGV;@ARGV>63&&exit 2}$.>=1e6&&exit 3;$_=printf"%5d\t%s",$.,$_'

Deparsed:
perl -MO=Deparse -ple'BEGIN{map{-r||exit 1}@ARGV;@ARGV>63&&exit 2}$.>=1e6&&exit 3;$_=printf"%5d\t%s",$.,$_' output.txt; echo $?

BEGIN { $/ = "\n"; $\ = "\n"; }
sub BEGIN {
    map {exit 1 unless -r $_;} @ARGV;
    exit 2 if @ARGV > 63;
}
LINE: while (defined($_ = <ARGV>)) {
    chomp $_;
    exit 3 if $. >= 1000000;
    $_ = printf("%5d\t%s", $., $_);
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

Important to know:

-p wraps the program given with -e in the while/continue loop
BEGIN code will be executed before the (implicit) main part
file test -r also fails if file doesn't exist !-e and defaults to testing $_, implicitly given in map { ... } @ARGV
$. holds the current line number
rest should be self-explanatory ;)

Great answer, and welcome to Programming Puzzles and Code Golf! Perhaps you could edit to add an explanation of how your code works.

C, 362 359
Just for the fun of it. ;-) Works with LF or CR/LF linefeeds.
#include<stdio.h>
#define R return
#define P printf(
e,t,l;void*f;r(){P"% 6d\t",++l);for(;(t=fgetc(f))^-1&&l<1000000;){if(ferror(f))R 1;P"%c",t);if(t==10)P"% 6d\t",++l);}P"\n");R l<1000000?0:3;}main(int c,char**v){e=c>65?2:0;for(++v;*v||c<2;++v){t=c<2||!strcmp(*v,"-")?f=stdin,0:!(f=fopen(*v,"rb"));if(t||(t=r()))e=!e|(e>t)?t:e;if(f&&f!=stdin)fclose(f);}R e;}

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


text:
Minimum excluded number
This is intended to be an easy, bite-size code-golf.
The mex (minimal excluded number) of a finite collection of numbers is the smallest non-negative integer 0, 1, 2, 3, 4, ... that does not appear in the collection. In other words, it's the minimum of the complement. The mex operation is central to the analysis of impartial games in combinatorial game theory.
Your goal is to write a program or named function to compute the mex using as few bytes as possible.
Input:
A list of non-negative integers in any order. May contain repeats. For concreteness, the length of the list and the allowed range of elements will both be between 0 and 20 inclusive.
The definition of "list" here is flexible. Any structure that represents a collection of numbers is fine, as long as it has a fixed ordering of elements and allows repeats. It may not include any auxiliary information except its length.
The input can be taken as a function argument or through STDIN.
Output
The smallest excluded number. Output or print it.
Test cases
[1]
0
[0]
1
[2, 0]
1
[3, 1, 0, 1, 3, 3]
2
[]
0
[1, 2, 3]
0
[5, 4, 1, 5, 4, 8, 2, 1, 5, 4, 0, 7, 7]
3
[3, 2, 1, 0]
4
[0, 0, 1, 1, 2, 2, 3]
4
[1, 0, 7, 6, 3, 11, 15, 1, 9, 2, 3, 1, 5, 2, 3, 4, 6, 8, 1, 18]
10

Restricting the numbers to a fixed range makes this problem even simpler.

@MartinBüttner If the array contains all number 0 to 20, the correct output is 21. I'll add a test case. Yes, the fixed range definitely makes it easier, though one could still arguably use sys.maxint or 2**64 if I didn't specify it.

No need for that test case. You said, the input can only contain 21 elements.

@MartinBüttner Right, fencepost. Thanks.

@xnor I cannot expect input array already on stack, can I ? :P

@Optimizer Nope.

@MartinBüttner - I read ".. the length of the list and the allowed range of elements will both be between 0 and 20 inclusive" to mean that the list will have at most 20 elements. So, the highest output would be 20, given a list of all numbers starting with 0 and ending with 19. Am I wrong?

@KevinFegan Yes, the maximum possible output is 20. My comment was mistaken and I think MartinBüttner typoed.

Pyth, 6 bytes
h-U21Q

Example run
$ pyth -c h-U21Q <<< '[5, 4, 1, 5, 4, 8, 2, 1, 5, 4, 0, 7, 7]'
3

How it works
  U21   range(21)
     Q  eval(input())
 -U21Q  setwisedifference(range(21), eval(input))          # Pyth function. Preserves order.
h-U21Q  setwisedifference(range(21), eval(input))[0]

When the set is converted to list, is it always in sorted order?

Pyth's set difference preserves the order of the first argument (range(21)), which is ordered. (This also means the explanation isn't entirely accurate. Pyth and Python 3 are both fairly new to me.)

To clarify, - in Pyth is actually a filter - it filters the first argument for absence from the second argument, then converts it to the form of the first argument (string, list or set).

Also, Dennis, it should be h-U22Q so it will give the correct output of 21 on the input containing the full allowable range.

@isaacg: The list's length is also limited to 20, so it cannot contain all 21 numbers from 0 to 20.

@Dennis Thanks, I should have read that more carefully.

CJam, 11 8 bytes
K),l~^1<

How it works:
K),         "Create an array with numbers 0 through 20"
   l~       "Read the input and eval it, resulting to an array"
     ^      "XOR the elements of two arrays, resulting in a complement array"
      1<    "Take the first element of the resultant array"

Sample input:
[1 0 7 6 3 11 15 1 9 2 3 1 5 2 3 4 6 8 1 18]

Output:
10

Try it online here

How high do the single-character numbers in CJam go?

@xnor Sadly, 20 - https://sourceforge.net/p/cjam/wiki/Variables/

A lucky choice!

J - 13 char
f=:0{i.@21&-.

Very simple actions in J, and thus very hard to make smaller.
i.@21 creates a list from 0 to 20 inclusive. -. performs set-subtracts the input from this list. 0{ takes the first element of what's left, i.e. the smallest number. f=: defines a named function. At the REPL:
   f=:0{(i.21)&-.
   f 1
0
   f 0
1
   f 2 0
1
   f 3 1 0 1 3 3
2
   f ''    NB. empty list
0
   f 1 2 3
0
   f 5 4 1 5 4 8 2 1 5 4 0 7 7
3
   f 3 2 1 0
4
   f 0 0 1 1 2 2 3
4
   f 1 0 7 6 3 11 15 1 9 2 3 1 5 2 3 4 6 8 1 18
10

Since the release of J806 in November 2017, a new syntax exists which saves us one byte by letting us use i.@21 for the old (i.21) in this context.

Do you need f=:?

Since November 2017 i.@21-.] would save 1 byte.

Brachylog, 4 bytes
ℕ≜¬∈

Try it online!
Works for any list size and any integer magnitudes.
Takes input from the Output variable, and outputs to the Input variable.
Explanation
ℕ      We want a non-negative integer
 ≜     Assign a value such that…
  ¬∈   …it is not an element of the list

Oddly enough, it looks like the ≜ can be dropped going the other way.

...Actually, the original version can handle an empty list, while this can't. Whoops

@UnrelatedString Reverted.

Jelly, 5 4 bytes
0ḟ1#

Try it online!
Doesn't use the bounds on the input.
...am I missing something?
0       Starting with 0,
  1#    find the first integer
 ḟ      which is not in the input.

Golfscript 7
~21,^0=

A further-golfed version of Peter Taylor's answer. Community wiki since I don't have the rep to comment on his post.
The difference is using the known max list size from the question instead of length +1 to save a character and dropping the irrelevant $.
Try it online

Dammit Golfscript for saving 1 character so as to not read the input -_-

Bash+coreutils, 23 bytes
seq 0 20|egrep -vwm1 $1

This assumes input as a | (pipe) separated list.  E.g:
$ ./mex.sh "5|4|1|5|4|8|2|1|5|4|0|7|7"
3
$

I don't think you need "(...)" around the $1.

Pipe-separated is fine, it meets the list-like condition of the spec.

If you take input separated by newlines, you can use grep instead of egrep

Burlesque -  9 Bytes
20rzj\\<]

Takes input from stdin in the format {7 6 5 5 1 2 2 4 2 0}
Explained:
 20 rz   map a range from 0 to 20. (thanks to algorithmshark for the cocde fix)
  j \\    swaps the two arrays, and collects the difference between the two into a new array
  <]      gets the smallest element of the resulting array.

Try some examples:
{1 0 7 6 3 11 15 1 9  2 3 1 5 2 3 4 6 8 1 18}20rzj\\<]
{5 4 1 5 4 8 2 1 5 4 0 7 7}20rzj\\<]

This fails to give any output on the input {0 1 2}, because you need to rz one more than the largest number. Just going straight for 20rzj\\<] fixes this and saves a char.

@algorithmshark No way around it, you are very right. Fixed. And thank you.

Jelly, 7 bytes
Ṁ‘‘Ḷḟ⁸Ḣ

Try it online!
How it works
Ṁ‘‘Ḷḟ⁸Ḣ  Main Link; argument is z
Ṁ‘‘      Takes 2 above the largest element in z
   Ḷ     Takes lowered range (thus returning [0, ..., max(z) + 1])
    ḟ⁸   Exclude all elements from the range that are also in z
      Ḣ  Take the first element (which is the smallest)

Thanks to @LeakyNun for -1 byte!

1 byte off

Trilangle, 53 bytes
'0.<_.\.>?0e#L_'\r/(&\,<.|.1.2S<.^#':2',.<..^\,!@.^)S

I'm not convinced this is optimal, but I've thought about it for a while and I don't think I can shrink it without substantial restructuring. I have proven that it's impossible to do this general approach without at least a grid of size n=8, and this is n=10.
Try it on the online interpreter!
Unfolds to this:
         '
        0 .
       < _ .
      \ . > ?
     0 e # L _
    ' \ r / ( &
   \ , < . | . 1
  . 2 S < . ^ # '
 : 2 ' , . < . . ^
\ , ! @ . ^ ) S . .

Equivalent to this C code:
#include <stdio.h>

// Read an integer from stdin, throwing out any separators. Returns -1 on EOF.
// Exact implementation is unimportant (and provided by the interpreter).
extern int getint(void);

int main() {
    // RED PATH
    // Keep a bitfield of the numbers that have been seen so far
    int field = 0;
    int i;
    while ((i = getint()) >= 0)
        // GREEN PATH
        field |= 1 << i;

    // BLUE PATH
    // Find the lowest nonzero bit
    int missing = 0;
    while (field & 1) {
        // MAGENTA PATH
        field >>= 1;
        ++missing;
    }

    // YELLOW PATH
    printf("%d\n", missing);
}

I am not doing an instruction-by-instruction walkthrough of this code. If you're interested, you can look into the disassembly feature of the interpreter.

Vyxal gH, 2 bytes
ʀ⊍

Try it Online! (Includes test cases)
   # H flag presets the stack to 100
ʀ  # inclusive range 0..100
 ⊍ # set difference
   # g flag takes the minimum of the top of stack after execution
   # which is implicitly output

Nekomata, 2 bytes
ᵏf

Attempt This Online!
ᵏf
ᵏ   Find the first natural number n such that:
 f  the input does not contain n

Ruby, 32 bytes
f=->n{(0..20).find{|i|n-[i]==n}}

Defines a function f to be called with an array.

Any comments from the downvoter? Did I miss some part of the spec?

I doubt it. Several other answers (including mine) got a mystery downvote.

@ipi but it does... in exactly the same format given in the examples in the challenge posts, e.g. f[[0, 1]] (where the outer brackets are invocation syntax and the inner brackets define the array).

Why do you need the f=?

Jelly, 7 bytes
Another approach. Can be used in a chain with any arity, and doesn't need chain separator or anything.
‘Ṭ;0i0’

Because the answer is guaranteed to be less than 256, this also works:
Jelly, 5 bytes
⁹ḶḟµḢ

Try it online!

Perl 6, 18 16 bytes
-2 bytes thanks to nwellnhof
{(0...*∉@_)-1}

Try it online!
Anonymous code block that counts up until it finds a number that is not an element of the input list, and returns the length of the range minus one

MathGolf, 5 4 bytes
Jr,╓

Try it online!
This solution is restricted to just the range 0 to 20, though this can be extended easily by increasing the initial range.
Explanation:
Jr     Range from 0 to 20
  ,    Remove elements from the input list from this range
   ╓   Return the minimum element

Alternatively, a 5 byte solution for all numbers:
Åï╧▲ï

Try it online!
Explanation:
Å  ▲   Do while true
  ╧    Does the input contain
 ï     The index of the loop?
    ï  Push the number of iterations of the last loop

With the new changes that are (hopefully) being added to TIO today, there's a 4 byte solution to this problem. It is restricted to an upper limit defined in the code, but since MathGolf has a 1-byte literal for 10^8, it shouldn't be noticeable.

This was the exact solution I had (I used Z instead of J because I was lazy).

Rust, 117, 113, 79 78 bytes
|l:&[u8]|{let mut r:Vec<_>=(0..22).collect();r.retain(|n|!l.contains(n));r[0]}

Attempt This Online!
Explanation
|l: &[u8]| {
    // Make a vector of the integers from 0 to 21
    let mut r: Vec<_> = (0..22).collect();
    // Keep only the numbers that aren't in the input
    r.retain(|n|!l.contains(n));
    // Return the first remaining number in the vector
    r[0]
}

JavaScript (ES6), 33 bytes
Thanks to @fhuvi for letting me know that my answer to this more recent challenge also works here.
a=>a.reduce(m=>m+a.includes(m),0)

Try it online!

GolfScript (10 9 bytes)
~.,),^$0=

Takes input from stdin in the format [5 4 1 5 4 8 2 1 5 4 0 7 7].
Online demo

Shouldn't the ; before the input string be counted in the program itself ?

@Optimizer, that's simulating input from stdin because the online GolfScript site doesn't support a separate input field.

Ruby, 22
x=->n{([*0..20]-n)[0]}

Explanation

Input is taken as an argument to a lambda. It expects an Array of Integers.
The input is subtracted from the array [0,1,2..20].
Because the Array [0,1,2..20] is sorted, the first element must be the mex.

Sweet, that was my first attempt, but I couldn't get the destructuring to work - I didn't think of surrounding it with brackets. Btw, you can use 20 instead of 21, because the input can only contain 20 elements.

Xojo, 55 bytes
dim x as int8
while a.indexOf(x)>-1
x=x+1
wend
return x

Haskell, 30
f s=filter(`notElem`s)[0..]!!0

This works for lists of all size and lists beyond 20. This can be made 15 bytes long if Data.List is imported:
f s=[0..]\\s!!0

Scheme - 219
(define (A X) (define (B X) (if (equal? (length X) 1) (+ (car X) 1) (if (< (- (cadr X) (car X)) 2) (B (cdr X)) (+ (car X) 1)))) (if (empty? X) `() (if (equal? (car (sort X <)) 0) (B (sort X <)) (- (car (sort X <)) 1))))

Not very competitive. But I like writing scheme :),
Here's the ungolfed code:
(define (minExclude X)
  (define (firstNonOneDifference X)
     (if (equal? (length X) 1)
         (+ (car X) 1)
     (if (< (- (cadr X) (car X)) 2)
         (firstNonOneDifference (cdr X))
         (+ (car X) 1)
     ))
  )
  (let ([s (sort X <)])
     (if (empty? X)
         `()
     (if (equal? (car s) 0)
        (firstNonOneDifference s)
        (- (car s) 1)
     ))
  )
)

R, 27 bytes
Reads from stdin; computes the first element in the set difference between [0..20] and x.
x=scan()
setdiff(0:20,x)[1]

R, 36 bytes
which.min(y%in%x) returns the index of the first element of y that is not in x.
x=scan()
y=0:20
y[which.min(y%in%x)]

Perl 5 -p, 28 bytes
$#i++;/\b$#i\b/&&redo;$_=$#i

Try it online!

Powershell, 28 bytes
for(;+$i-in$args){$i++}+$i

Test script:
$f = {
 for(;+$i-in$args){$i++}+$i
#for(;$i++-in$args){}(--$i)   # alternative version
}

@(
    ,(0 , 1)
    ,(1 , 0)
    ,(2 , 3, 1, 0, 1, 3, 3)
    ,(0 )
    ,(0 , 1, 2, 3)
    ,(3 , 5, 4, 1, 5, 4, 8, 2, 1, 5, 4, 0, 7, 7)
    ,(4 , 3, 2, 1, 0)
    ,(4 , 0, 0, 1, 1, 2, 2, 3)
    ,(10, 1, 0, 7, 6, 3, 11, 15, 1, 9, 2, 3, 1, 5, 2, 3, 4, 6, 8, 1, 18)
) | % {
    $e, $a = $_
    $r = &$f @a
    "$($r-eq$e): $r"
}

Output:
True: 0
True: 1
True: 2
True: 0
True: 0
True: 3
True: 4
True: 4
True: 10

Explanation:

Increment $i while the $args array contains the integer value +$i.
Output a last integer value +$i.

Can be shortened down to 24 bytes :)

Prolog (SWI), 64 35 bytes
-29 bytes thanks to @Jo King
L+X:-between(0,20,X),\+member(X,L).

Try it online!

Vyxal r, 7 5 4 bytes
₇ʀFg

-2 bytes thanks to lyxal
-1 byte thanks to Steffan
Try it online or verify all test cases.
Explanation:
 ʀ    # The range 0 to
₇     # 128
  F   # Filter out items from the range that are in the input list
      # (The r flag swaps the arguments)
    g  # Get the lowest one

Try it Online! for 5 bytes

Try it Online! for test cases

@lyxal Smart, thank you

4 bytes with r flag: Þ∞Fh

@Steffan That doesn't work for the [1] test case, but you can just remove the $ and from Lyxal's one and add the r flag

Thunno, \$ 9 \log_{256}(96) \approx \$ 7.41 bytes
21RAq0sAh

Attempt This Online!
Explanation
21RAq0sAh  # Implicit input                     INPUT: [4, 1, 0, 2]
21R        # Push range(21)                     STACK: [4, 1, 0, 2], [0..20]
   Aq      # Check whether each of the items    STACK: [1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
           # in the input occurs in range(21)
     0sAh  # Find the index of the first 0      STACK: 3
           # (0-indexed)
           # Implicit output

Julia 0.6, 22 bytes
>(x,i=0)=i∈x?x>i+1:i

Try it online!
Minimally adapted from MarcMush's recursive solution to a related challenge.
Julia 0.6 supports ternary operators without spaces, which were deprecated in 0.7 and removed in 1.0.

Python, 37 characters
f=lambda a:min(set(range(21))-set(a))

Beat me by a couple of seconds. BTW, it's range(21).

This seems to be the shortest solution. The recursive solution f=lambda l,i=0:i in l and f(l,i+1)or i is one char longer and the iterative solution i=0;l=input()\nwhile i in l:i+=1\nprint i is two chars longer (not storing the input makes it be taken repeatedly). Without the 20 bound, I think these approaches would prevail.

Couldn't this be an anonymous function? If it could, you can save 2 bytes.

C# - 64 chars
int f(int[] a){return Enumerable.Range(0,20).Except(a).First();}

Not always Rarely the best golfing language, but is easy to write and understand :)

Java 7, 69 66 bytes
int c(java.util.List a){int r=0;for(;a.contains(r);r++);return r;}

-3 bytes thanks to @LeakyNun
Explanation:
Supports not only 0-20, but 0-2147483647 instead (which actually saves bytes).
int c(java.util.List a){    // Method with List parameter and integer return-type
  int r=0;                  //  Return integer
  for(;a.contains(r);r++);  //  Continue raising `r` as long as the list contains the current `r`
  return r;                 //  Return result-integer
}                           // End of method

Test code:
Try it here.
import java.util.ArrayList;
import java.util.Arrays;
class M{
  static int c(java.util.List a){int r=0;for(;a.contains(r);r++);return r;}

  public static void main(String[] a){
    System.out.println(c(Arrays.asList(1)));
    System.out.println(c(Arrays.asList(0)));
    System.out.println(c(Arrays.asList(2, 0)));
    System.out.println(c(Arrays.asList(3, 1, 0, 1, 3, 3)));
    System.out.println(c(new ArrayList()));
    System.out.println(c(Arrays.asList(1, 2, 3)));
    System.out.println(c(Arrays.asList(5, 4, 1, 5, 4, 8, 2, 1, 5, 4, 0, 7, 7)));
    System.out.println(c(Arrays.asList(3, 2, 1, 0)));
    System.out.println(c(Arrays.asList(0, 0, 1, 1, 2, 2, 3)));
    System.out.println(c(Arrays.asList(1, 0, 7, 6, 3, 11, 15, 1, 9, 2, 3, 1, 5, 2, 3, 4, 6, 8, 1, 18)));
  }
}

Output:
0
1
1
2
0
0
3
4
4
10

Heh, libraries.

3 bytes off

Java, 91 bytes
int f(int[]a){int i=0,j=1,k;for(;j>0;i++)for(k=j=0;k<a.length;j=a[k++]==i?1:j);return i-1;}

Try it online!

APL (Dyalog), 19 bytes
(0⍳⍨⊢=⍳∘⍴)∘(⊂∘⍋⌷⊢)∪

Try it online!
I am probably missing out something important here. Golfing in progress...

TI-BASIC, 24 bytes
:0→A                 //Store 0 to A
:Prompt X            //Prompt list X
:While not(prod(ʟX-A //While A is not missing from list X
:A+1→A               //Increment A
:End                 //End While loop
:A                   //Print A

If Prompt X is given a list instead of a single number, it will automatically create a list named X that can be accessed with ʟX.

20 bytes using Ans: Prompt X:0:While not(prod(ʟX-Ans:Ans+1:End:Ans

Scala, 18 bytes
0 to 20 diff l min

l is a list of Int.
scala> val l = List(0,1,5)
l: List[Int] = List(0, 1, 5)

scala> 0 to 20 diff l min
res0: Int = 2

PHP, 38 Bytes
<?=min(array_diff(range(0,20),$_GET));

PHP, 39 Bytes
<?for(;in_array($i++,$_GET););echo$i-1;

Japt, 7 bytes
@!UøXÃa
@    Ãa # Starting from zero, find the smallest integer
 !UøX   # that's not present in the input array.

Try it online!

Stax, 6 bytes
¢╔⌂♀╠▬

Run and debug it
Explanation
21r:IUI             # Full program, unpacked
21                  # Push 21
  r                 # Range from 0...20
   :I               # Find all elements in input that exist in range
    U               # push -1
     I              # Get index of first occurrence of

F#, 38 bytes
let f s={0..20}|>Seq.except s|>Seq.min

Try it online!
Fairly straight-forward to be honest...

Lua, 92 bytes
x=function(a,...)q=...or 0 for i=0,#a do if a[i]==q then return x(a,q+1)end end return q end

This seems way too long.
Try it online!

88 bytes

APL (Dyalog Classic), 11 bytes
f←⊃⊢~⍨0,⍳∘⍴

Try it online!

Wolfram Language (Mathematica), 29 bytes
Min@Complement[0~Range~20,#]&

Try it online!

Stax, 5 bytes
wiix#

Run and debug it
w      run until condition is satisfied
 ii    push iteration index twice
   x#  number of times iteration index appears in input (non-zero is truthy)

When the loop is finished, the final iteration index will be on top of the main stack, and implicitly printed.

Python 2, 36 bytes
lambda a,i=0:i in a and f(a,i+1)or i

Try it online!

k, 7 bytes
*(!22)^

Try it online!
 (!22)  /[0, 1, 2, ..., 21]
      ^ /set difference between [0, 1, 2, ..., 21] and input (called exclude)
*       /get first element

For an arbitrary positive maximum instead of 20, the smallest I have so far is 13 bytes:
{*(!2+|/x)^x}

Factor, 27 bytes
[ 21 iota swap diff first ]

Try it online!
       ! { 3 1 0 1 3 3 }
21     ! { 3 1 0 1 3 3 } 21
iota   ! { 3 1 0 1 3 3 } { 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 }
swap   ! { 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 } { 3 1 0 1 3 3 }
diff   ! { 2 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 }
first  ! 2

Desmos, 52 bytes
L=[0...20]
f(l)=L[[(i-join(e,l))^2.minfori=L]>0].min

Try It On Desmos!
Try It On Desmos! - Prettified

Zsh, 31 bytes
for ((;$@[(I)$[i]];i++)):
bye i

Attempt This Online!
Outputs via exit code.

05AB1E, 6 5 bytes
₂ÝIKн

-1 byte thanks to @emanresuA
Try it online or verify all test cases.
Explanation:
₂Ý     # Push a list in the range [0,26]
       # (26 is the smallest 1-byte constant above 19)
  IK   # Remove all values of the input-list from this ranged list
    н  # Pop and push the first integer remaining (which is the minimum)
       # (which is output implicitly as result)

Would using a builtin number larger than 20 save bytes?

@emanresuA It indeed would, thanks.

Japt, 5 bytes
@øX}f

Try it here
@øX}f     :Implicit input of array U
@         :Function taking an integer X as an argument
 øX       :  Does U contain X?
   }      :End function
    f     :First integer >=0 that returns false when passed through that function

Japt -g, 5 bytes
Lo kU

Try it
Lo kU     :Implicit input of array U
L         :100
 o        :Range [0,L)
   kU     :Remove the elements of U
          :Implicit output of first element

Fig, \$5\log_{256}(96)\approx\$ 4.116 bytes
[FxmN

Try it online!
Works for all numbers.
[FxmN
   mN # All natural numbers [0, 1, 2, 3, ...]
 Fx   # Remove the inputs
[     # Take the first one remaining

Pip, 7 bytes
WiNgUii

Takes input as separate command-line arguments. Try It Online!
Explanation
WiNgUii
W        While
 i       a number (initially 0)
  N      is an element of
   g     the list of command-line args:
    Ui     Increment the number
      i  Output the final value

Haskell, 26 bytes
f l=until(`notElem`l)(+1)0

Try it online!

x86_32 machine code, 14 13 bytes
-1 byte thanks to l4m2
Expects the array in EDI (as a uint8_t*) and the length in ECX as an integer. Returns output in EAX.
31 c0 9e 60 f2 ae 61 75 03 40 eb f7 c3

Try it online!
Explanation
; eax=int calc_mex(edi=uint8_t* nums, ecx=int length)
calc_mex:
  31 c0                   xor eax, eax ; N to look for (start at 0)

  ; Store 0 to EFLAGS so that when length is zero and scasb never runs,
  ; ZF is set to zero to return the proper result (0).
  9e                      sahf

loop:
  60                      pushad ; Store ECX and EDI

  ; Search for AL in *EDI. If it doesn't exist, return AL; if it does,
  ; increment AL and search again.
  f2 ae                   repne scasb

  61                      popad ; Restore ECX and EDI

  ; If AL was not found (ZF=0), return as we found the minimum.
  75 03                   jnz return

  ; Otherwise, keep looping.
  40                      inc eax
  eb f7                   jmp loop

return:
  c3                      ret

Why check ecx rather than ZF?

@l4m2 When inc ecx is removed and jecxz is converted to jnz, the empty list test case fails as scasb doesn't run and the jump is done based off of unrelated instructions (xor eax, eax on the first iteration and inc eax on the second). When inc ecx remains, test cases will fail randomly as al will occasionally be found in the extra checked byte.

-1

Haskell + hgl, 8 bytes
he<bD nn

Attempt This Online!
Explanation

bD nn all non-negative integers not in the input
he get the first.

Reflection
This is a very straight-forward solution to a very simple problem. The only thing I might say is that it could possibly be worth having a built-in for "The smallest natural number such that ...". Assuming that would be 3 bytes the built in would save 2 bytes in this case.

Pascal, 148 bytes
This is a complete program meeting the specifications of ISO standard 7185 “Standard Pascal”.
It expects a newline-separated possibly empty list of integers in the range 0..20.
program p(input,output);var i:0..20;s:set of 0..20;begin s:=[];while not EOF do begin readLn(i);s:=s+[i]end;i:=0;while i in s do i:=i+1;write(i)end.

Ungolfed:
program minimumExcludedNumber(input, output);
    var
        i: 0..20;
        s: set of 0..20;
    begin
        { transform ordered list to “unordered” `set` ―――――――――――――――――――――― }

        { Initialize `s` as an empty set. }
        s := [];
        { This needs to be a head-controlled loop in order to
          take account of a possibly _empty_ list of integers. }
        while not EOF do
        begin
            readLn(i);
            s := s + [i]
        end;

        { analyze step: find first `integer` not part of set ――――――――――――――― }

        { Starting at zero “skip” all _included_ numbers in `s`. }
        i := 0;
        while i in s do
        begin
            { This is guaranteed not to cause an error [this concerns the case
              that `i` equals 20], because as per specification “the length of
              the list […] will […] be between 0 and 20 inclusive.” Specifying
              all integers in the interval `0..20` would require _21_ items. }
            i := i + 1
        end;
        write(i)
    end.

See also natural supremum code golfing task and answer.

Nibbles, 2.5 bytes (5 nibbles)
/-`,~

Attempt This Online!
/-`,~    # full program
/-`,~$$  # with implicit args
 -   $   # remove the input from
  `,~    # infinite list 0..infinity
/     $  # and fold from right over the resulting (infinite) list,
         # returning the left-hand element each time

*><>, 100 bytes
v           v       /&~1+I]:&1[D>20.
>l:?!\:1[D&0>:}}:{=?/&1-:&?!\{$}^
;n   /!                    {/

This one's a bit convoluted, so I don't plan on doing a full write-up. The gist, though, is to keep the initial input length (IIL) on a stack above our main one, keep the current index (CI) of the input that we're checking in the register, and to keep a counter value on the stack, leaving it at the 0th index when it comes time to print it.
Checks for a value in the input by starting at the end of the input, and moving forward.
Initialization - The part of Line 1 & 2 I don't mention later
v
>l:?!\:1[D&0

Ensure the IP is on Line 2, and moving to the right
Get the length of the input
If it's 0, move down to Line 3 and print that
Otherwise, duplicate that IIL, and put one copy on a stack above our current one
And put another copy into the register

Line 1 - Counter value is in input
/&~1+I]:&1[D>20.

Dump the register
Collapse the IIL down onto the current stack
Push a copy of the IIL into the register
Recreate the stack containing the IIL
Move the IP to [0, 2] in the code, placing it before the second v

Line 2 - Test counter == input[CI], and handle not equal case
>:}}:{=?/&1-:&?!\{$}^

Ensure IP is moving to the right
Duplicate the counter and input[CI]
Move the stack such that a copy of the counter and a copy of the current index are next to each other
If equal, move to Line 1
Otherwise, reduce the CI by one
Check if CI == 0, if so, move to Line 3
Otherwise,
Reduce CI by 1
Move the last element of the input to input[1]
Move up to Line 1, just before the jump to [0, 2], essentially creating a do ... while (...) loop

Line 3 - Print
;n   /!                    {/

If we're printing from Line 2, shift the counter value to the end of the stack

Try it online!

Perl - 34
Here's a subroutine.
sub f{$_~~@_?1:return$_ for0..20}

Test with:
perl -e'print f(0,1,3,4,5,6,7); sub f{$_~~@_?1:return$_ for 0..20}'

Java, 93
int f(int[]a){int i=0,j=0,k=a.length;for(;i++<20&j<k;){for(j=0;j<k&&a[j++]!=i;);}return i-1;}

Ungolfed:
int f(int[] a) {
    int i = 0, j = 0, length = a.length;
    for (; i < 20 & j < length; i++) {
        for (j = 0; j < length && a[j] != i; j++) { }
    }
    return i - 1;
}

Produces -1 for test case [].

Cobra - 50
def f(l)
    for n in 22,if n not in l,break
    print n

Javascript, 74
i=-1;a=prompt().split(',');while(i<21&&a.indexOf(String(++i))>=0);alert(i)

Nice and simple! Note the empty while loop.

JavaScript (E6) 35
Recursive function, array parameter in input and returning the mex. Not limited to 20
F=(l,i=0)=>~l.indexOf(i)?F(l,++i):i

Test in FireFox/FireBug console
;[[1],[0],[2, 0],[3, 1, 0, 1, 3, 3],[],[1, 2, 3],
[5, 4, 1, 5, 4, 8, 2, 1, 5, 4, 0, 7, 7],[3, 2, 1, 0],[0, 0, 1, 1, 2, 2, 3],
[1, 0, 7, 6, 3, 11, 15, 1, 9, 2, 3, 1, 5, 2, 3, 4, 6, 8, 1, 18]]
.forEach(list => console.log(list, F(list)))

Output
[1] 0
[0] 1
[2, 0] 1
[3, 1, 0, 1, 3, 3] 2
[] 0
[1, 2, 3] 0
[5, 4, 1, 5, 4, 8, 2, 1, 5, 4, 0, 7, 7] 3
[3, 2, 1, 0] 4
[0, 0, 1, 1, 2, 2, 3] 4
[1, 0, 7, 6, 3, 11, 15, 1, 9, 2, 3, 1, 5, 2, 3, 4, 6, 8, 1, 18] 10

Pyth, 6 bytes
f!}TQZ

Test suite
Makes no assumptions on the contents of the list.
Explanation:
f!}TQZ | Full code
-------+--------------------------------
f    Z | First T starting at 0 such that
 !}TQ  |  T is not in the input

Pyt, 7 bytes
05²Ř←\↓

Try it online!
  05²Ř           generate [0,1,2,...,25]
  ←              get input
  \              set difference
  ↓              get minimum; implicit print

Arturo, 27 17 bytes
$=>[min--@0..20&]

Try it
$=>[       ; a function
    min    ; minimum of
    --     ; difference of
    @0..20 ; 0..20, reified
    &      ; and input
]          ; end function

JavaScript (Node.js), 37 bytes
Only 4 bytes above the best JS solution :'(
l=>l.sort().map(b=>a=a<b?a:b+1,a=0)|a

Try it online!

Stax, 6 bytes
21r|^h

Run and debug it
This is my first answer in Stax, so I may be missing some builtin that helps.
Explanation
21r|^h #
21r    # range 0..20
   |^  # setwise difference with the input
     h # first element

Java 8 (OpenJDK 8), 49 bytes
Solution using only inline stream :
l->l.stream().sorted().reduce(0,(a,b)->a<b?a:b+1)

Try it online!

GNU sed, 127 bytes
s/.*/ & %-,-0123456789#/;:1;s/%0*(.*)(.)(,.*\2)(.)/%0\1\4\3\4/;s/(.)#(.*\1)(.)/\30\2\3/;/ (\S*) .*%0*\1,/b1;s/.*%0*(..*),.*/\1/

Try it online!
Without the array limit, six more bytes are needed for the inner loop that handles the 99->100 case:
s/.*/ & %-,-0123456789#/
:1
s/%0*(.*)(.)(,.*\2)(.)/%0\1\4\3\4/
:2
s/(.)#(.*\1)(.)/\30\2\3/
t2
/ (\S*) .*%0*\1,/b1
s/.*%0*(..*),.*/\1/

Z80 machine language, 11 bytes
Base address of list in HL, length in BC.
AF C5 E5 ED B1 E1 C1 C0 3C 18 F6

Returns with mex in A unless it's at least 256, then never returns.
If you replace the last two bytes with B7 20 F5 C8 then it returns with mex in A if it's at most 255 and with the zero flag OFF, else with 0 in A and zero flag ON.
    xor a
l:  push bc
    push hl
    cpir // 8086: repnz scas
    pop hl
    pop bc
    ret nz
    inc a
    jr l

The alternative above replaces jr l with:
    or a
    jr nz,l
    ret

authors: Никита Угрюмов

authors: Сергей Домин

authors: عبدالله الفيفي

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


text:
Help me with trigonometry!
Thank you guys so much for your help with calculus. Now I need some help with my upcoming trigonometry test.
On the test, I'll need to simplify expressions. I’ll be given input like 4sin(x)/(2cos(x)) and will have to produce a simpler, but equivalent expression (such as 2tan(x)). All angles are in degrees, and we'll pretend there are no division-by-zero or invalid-domain issues. (For example, we'll assume that tan(x+1)cot(x+1)sin(x)/sin(x) is always 1.)
I snuck into the professor's office, and got a list of 100 problems that might be on the test. Please give me teh code to solve them all. It’s possible that some of the problems are already simplified as much as possible; if so just give back the input.
I need expressions to be simplified, but I also want a short program (or function) so the professor won't notice. Try to minimize the sum of the program’s length and the total length of all of the solutions.
Just to clarify, it's okay if some of the expressions are returned unchanged, or even returned in an equivalent but longer form. Also, the program only needs to work on the expressions listed below; it can return incorrect results or even break for other inputs.
As you can tell, all of the problems follow a similar format. x is the only variable used, there are no spaces, and parentheses follow each function name. (The functions are sin, cos, tan, sec, csc, and tan.) There are no nested functions, but inside a function may be an expression like 3x+4.5 or -2-.7x. Exponents may be used, but only on functions (e.g. sin(x-.5)^7), and the power is always a integer above one. Multiplication is indicated through concatenation.
The outputs will need to be in this format as well. Invalid: sin x, sin(x)/cos(x)tan(x) [is the tangent multiplied or divided?], cos(x [close all parentheses], 4*sin(x), sec(x)^1
I can use any programming language, unless it relies on built-in simplification or expression-handling functions. Built-in trig functions are okay. (I'll have a very basic scientific calculator during the test.) Also, since I'll be reading the program written on paper, I can only use printable ASCII characters (0x20 through 0x7E) and newlines.
1/(sec(x))
4+sin(x)+3
(cos(7x+4)-sin(-3x))/(sin(-3x))
2sin(x)2tan(x).25cos(x)^3cos(x)+1+1
7cos(x)sec(x)/(14tan(x)csc(x))
sin(x)cos(x)/sec(x)
8sin(x)cos(x)sin(x)/tan(x)+8sin(x)
sin(x)^9cos(x)cot(x)sec(x)csc(x)sec(x)tan(x)/(cot(x)^2tan(x)cos(x)^4cot(x)sin(x))
tan(x)cos(x)csc(x)
tan(x+1)sin(x-1)cos(x+1)^3tan(x-1)^2sin(-x+1)csc(x+1)tan(-x+1)/(cos(x-1)cot(x+1))
(cos(2x)+cot(2x)-sin(2x)+csc(2x)^3)/(cot(2x)+sin(2x))
cos(90-x)cos(x)
sin(x+180)sec(450-x)
tan(-x)sin(x+90)sec(x-90)
tan(x+180)^2
cot(-x)cos(-x)
cot(180-x)^3cos(270-x)^2
sin(.1x-.2)sin(.1x-.2)sin(.1x-.2)sin(.2-.1x)sin(.2-.1x)
sin(x)
sin(90-x)sin(x)+cos(90-x)/sec(x)
tan(3x+2)cos(3x+2)/sin(3x+2)-1
cos(x)cos(x)cos(x)cos(x)cos(x)
sec(2x+1)sec(-1-2x)+sec(-2x-1)sec(2x+1)
cos(4x)cot(4x)tan(4x)sin(4x)csc(4x)
-cos(x)+cos(x)+sin(2x-4)-1/csc(2x-4)
sec(x)sec(x+2)cot(x)tan(x-2)tan(x+180)
tan(x)(tan(x))
3sin(x)sin(x)/(3)
cos(x)sin(x)
tan(x)sec(x)^2
tan(x)^2-sec(x)^2
7+sin(x)csc(x)csc(x)+cot(x)^2
sin(90)+cos(-90)+sec(180)
csc(1)+csc(10)-csc(30)-csc(60)+csc(90)
sin(36000001)
csc(800)+(cot(720+x)-sec(4x-720))
sin(-x)+sin(x)
csc(-x)+csc(x)
4sin(x)-sin(x)+tan(x)-2tan(x)
cot(x)+10cot(x+90)+99cot(x+180)+.01cot(x-90)
tan(x)tan(x+180)
sec(x)sin(x+180)tan(x-270)cot(x-450)csc(x+90)
sin(x)/cot(x)+sin(x)/cot(x)
sin(x)csc(x)+tan(x)cot(x)+cos(x)sec(x)
cot(x)
9tan(x+90)+90tan(x+9)
cos(x-9999)+tan(x+99999)
2tan(x)tan(x)/2
tan(x)/tan(x-360)+cos(x+180)/cos(x)
csc(4x)sec(270-4x)
cot(91+x)tan(x-449)
csc(2x)(csc(2x)-sin(2x))
csc(x+1)^2-cot(x+1)cot(x+1)
cot(x)cot(x)+1
tan(x)^2-sec(x)sec(x)
tan(x)/cot(x)+csc(x)/csc(x)
cot(x)sin(x)/cos(x)
csc(x)tan(x)cos(x)
csc(x)cot(x)cos(x)
csc(x+90)csc(-x+270)-1
cot(x)/cot(x)+tan(x)/cot(x)+cot(x)cot(x)
sec(x)sec(x)sec(x)sec(x+90)sec(x-90)sec(x+180)
1-cos(x)cos(x+180)+sin(x)^2
sec(x)sec(x)sec(x)sec(x)/cos(x)+cot(x)
cot(x+1)csc(x-1)sec(x+1)tan(x-1)sin(x+1)cos(x-1)
sin(x)-cos(x)+tan(x)-sec(x)+cos(x)-csc(x)
tan(x+23515)-sec(-.27x-23456)
sec(-.9x)
-tan(-x)-csc(360-x)
cos(-x)sec(x)sin(x)csc(-x)
tan(-x)^2-sin(-x)/sin(x)
tan(x)tan(x)+1
csc(x)^2-1
cot(2x)cot(2x)-csc(2x)/sin(2x)
2sec(x)/(6cos(x))
sec(0)+tan(30)cos(60)-csc(90)sin(120)cot(150)+tan(180)csc(210)sin(240)-cos(270)sec(300)+cot(330)
tan(x-1234567)sec(4781053+x)^2
tan(-1234567x)sec(4781053x)^2
sin(x)^9+cos(x)^7+csc(x)^5-cot(x)^3
cos(-33x-7.7)
sec(-.1-x)+tan(-2x-77)
tan(x)+sin(x)-cos(x)+tan(x)-sin(x)
cos(x)-sec(x)/tan(x)+tan(x)/sin(x)
cot(x)-cos(x)/sin(x)
3cos(x)+2/sec(x)-10sin(x)/(2tan(x))
tan(x+3)^11+sin(x+3)^8-cos(x+3)^5+5
sec(x)+sec(x)
csc(.1x)csc(-.1x)csc(x)
cot(x-7)cot(x-7)cot(x+173)cot(x-7)cot(x+173)cot(x-367)
cos(.0001x+1234567)
cot(45)+tan(225)-sin(210)+cos(-60)
sin(12345)cos(23456)tan(34567)sec(45678)csc(56789)cot(67890)
cos(1234x)+cot(1234)+tan(1234x)+sec(1234)+csc(1234)+sin(1234x)
sec(x)sec(x)sec(x)sec(x)sec(x)sec(x)
csc(x)cot(x)sec(x)csc(x)tan(x)sec(x)cot(x)csc(x)cot(x)cos(x)cos(x)cot(x)sin(x)sin(x)cot(x)
csc(2553273)+cot(1507348)-sec(5518930)+csc(5215523)+tan(3471985)-sec(4985147)
sin(20x)+cos(20x)-tan(20x)+sin(20x)-csc(20x)+cot(20x)-tan(20x)+csc(20x)
cot(100000)+cot(100000x)+cot(100000x)+cot(100000)
csc(5x+777)sin(5x+777)
csc(4.5x)

Note: This scenario is entirely fictional. In real life, cheating and helping others cheat is wrong and should never be done.

I count no less than forty different identities and mathematical axioms that would be needed to simplify this. Even parsing one of the expressions and getting it into some kind of structured internal form would take a fair bit of code. Too rich for me. But maybe there are some here looking for this kind of a challenge.

@COTO you don't have to parse it. You can try to detect which problem it as and hardcode the answers in compressed form. It might even be shorter than parsing.

@IngoBürk: After re-reading the OP, I would have to agree. "the program only needs to work on the expressions listed below" is pretty forgiving.

if your printer cannot print any non-ASCII character, you need a better printer.

Are we allowed to use sqrt? This seems like it will happen quite a bit and we can't use ^.5.

I just thougth WTF this guy even got UPVOTES? Then I noticed that it wasn't math.SE, soo... context matters=)

Also, how do we simplify expressions with an undefined value? csc(0) is not defined (in the complex plane)

@IngoBürk No sqrt

@IngoBürk I changed the offending values. (I understand it's usually a really bad idea to change the problem once posted, but in this case there was no choice.)

@Ypnypn I think the change was a bad idea. I just got done with my answer. Luckily, it doesn't change any of my code and also doesn't allow for good simplifications.

Are there any requirements for the precision of purely numerical answers?

@DigitalTrauma Infinite precision, e.g. 2/3 != 0.666666667; sin(45) != 0.707.

@Ypnypn Oh, ok, so for example we can't reduce sin(36000001)  to .017452

Python, 436 + 1909 = 2345
This must be one of the most inefficient solutions imaginable and mathematicians will probably cringe, but I've managed to throw something together that actually simplifies about half of the expressions without any hardcoding:
from math import*
import exrex,re
d=lambda f:lambda x:f(x*pi/180)
sin,cos,tan=d(sin),d(cos),d(tan)
i=lambda f:lambda x:1/f(x)
sec,csc,cot=i(cos),i(sin),i(tan)
t=lambda s:[round(eval(re.sub('([\d\).])([\(a-z])','\\1*\\2',s).replace('^','**')+'+0')*1e9)for x in[1,44]]
def f(I):
 try:return min((s for s in exrex.generate('(-?\d|\(1/\d\.\))?([+-]?(sin|cos|tan|cot|sec|csc)\(x\)(\^\d)?){0,4}')if s and t(s)==t(I)),key=len)
 except:return I

The output for the 100 test cases should be the following (where # marks expressions that were not simplified):
cos(x)
7+sin(x)
#
2+tan(x)^2cos(x)^2
(1/2.)cos(x)
sin(x)cos(x)^2
#
sin(x)^2tan(x)^7
1
#
#
sin(x)cos(x)
-1
-1
tan(x)^2
-cot(x)cos(x)
-cot(x)cos(x)^2
#
sin(x)
2sin(x)cos(x)
0
cos(x)^5
#
#
#
#
tan(x)^2
sin(x)^2
sin(x)cos(x)
tan(x)sec(x)^2
-1
7+cot(x)^2+csc(x)
0
#
#
#
0
0
3sin(x)-tan(x)
#
tan(x)^2
-tan(x)sec(x)
2sin(x)tan(x)
3
cot(x)
#
#
tan(x)^2
0
#
1
#
1
csc(x)^2
-1
sec(x)^2
1
1
cot(x)^2
-1-sec(x)^2
cot(x)^2+sec(x)^2
sec(x)^4csc(x)^2
2
cot(x)+sec(x)^5
#
sin(x)+tan(x)-csc(x)-sec(x)
#
#
tan(x)+csc(x)
-1
sec(x)^2
sec(x)^2
cot(x)^2
-1
(1/3.)sec(x)^2
#
#
#
#
#
#
2tan(x)-cos(x)
cos(x)-csc(x)+sec(x)
0
0
#
2sec(x)
#
#
#
3
#
#
sec(x)^6
cot(x)^4csc(x)
#
#
#
1
#

The idea is quite simple:

generate a huge amount of possible expressions
select those that yield the same result as the expression you want to simplify, comparing them for some (here two) x values
from the equivalent expressions return the shortest one

The problem is that there are quite a lot of possible expressions to check, so I limited it to a subset.
To be honest I was not patient enough to test the golfed code above. (Tell me if you think that's cheating.) Instead I used a much longer but more efficient rule to generate an even smaller subset of expressions that hopefully still contains all the desired simplifications. Should you want to try that, replace the regular expression in the second to last line of the code with the following (and be prepared for a few minutes of computation time):
'0|((-1|\(1/[23]\.\)|[1237])[+-]?)?(sin\(x\)(\^2)?)?-?(tan\(x\)(\^[27])?)?(cot\(x\)(\^[24])?)?[+-]?(cos\(x\)(\^[25])?)?(sec\(x\)(\^[2456])?)?(csc\(x\)(\^2)?)?'

The program also contains quite some overhead that was needed to make Python understand the mathematical expressions. This involved

redefining sin,cosand tan to take arguments in degrees instead of radiens (which is what I think the OP intended)
defining sec,csc and cot which are not part of the math package
inserting all the implied multiplication signs
replacing the exponentiation operator

@Doorknob How is brute-forcing expressions and comparing two values any more of a "real solution" than the others?

@Emil Since you only compare two different values for `x', have you somehow ensured that simplifications are actually correct?

Giving it a quick look I can't find incorrect simplifications (impressive), but to my understanding 1/3.sec(x)^2 is not valid output.

@IngoBürk, all the answers were calculated by hand or with WolframAlpha first and I later compared these with the program's output. In two or three cases the program actually found simplifications that WolframAlpha did not output, but I could confirm that theses were correct too. But of course you're right, there could potentially be collisions. It's just that the nature of the functions in question make it quite unlikely that two distinct graphs should intersect at my two points within the used accuracy. I've seen collisions if I use just one point or if the two points are too close together.

Oh, I see, the two outputs involving fractions are indeed against the OP's specifications. The shortest option would be sec(x)^2/3but that was hard to implement in my regex without causing problems elsewhere. I think I'll just add parentheses.

@Emil Alright. I really love this solution btw!

CJam, 1 + 3000 = 3001
Just as the baseline solution to give people something to beat:
l

This reads STDIN onto the stack, whose contents are printed at the end of the program.
I'm sure this can be beaten, but I'm also sure that many optimisations can't be implemented in the characters that would be gained.

Was it stated anywhere how to calculate the score? I like your method. However, I would not consider the newlines, so that the base score would be 3000.

@Emil "Try to minimize the sum of the program’s length and the total length of all of the solutions." – I had to read it several times as well.

I wonder why Martin didn't use Golfscript. No need to explicitly read the input there =D

I don't understand. How is this answer and the below one anyhow related to the question, which asks about trigonometry and stuff

@Optimizer It is perfectly legal to just return the input as the "simplified" expression.

@IngoBürk Because I don't know GolfScript. :P

Along similar lines, you can use a zero-length sed program

Javascript (438 + 2498 = 2936)
The object in the middle optionally contains simplified outputs based on the length of the input and the first character. Otherwise, the input is returned unmodified.
s='sin(x)';(p=prompt)({
    352:s+"^2cos(x)^3+2",
    307:"cos(x)/2",
    348:s+"8(1+cos(x)^2)",
    "81s":s+"^2tan(x)^7",
    "55s":"-sin(0.2-0.1x)^5",
    "39s":"2sec(2x+1)^2",
    "35c":"cos(4x)",
    "36-":0,
    173:s+"^2",
    "25s":0,
    294:s+"3-tan(x)",
    "27s":s+"2/cot(x)",
    "40c":"1+tan(x)^2+cot(x)^2",
    "48c":1,
    "41s":s+"+tan(x)-csc(x)-sec(x)",
    "26c":-1,
    "24t":"1+tan(x)^2",
    "96s":"2.5+1/cos(30)",
    "34t":"2tan(x)-cos(x)",
    353:0,
    "36s":"6sec(x)",
    "90s":"cot(x)^4csc(x)"
}[(i=p()).length+i[0]]||i)

The whitespace is just for decoration and not included in the character count.
It's a shame that adding all these solutions only saved me a few characters, but better than nothing. The simplification was done via wolframalpha – I'll just trust it.


text:
Enclose 1009 pixels
Output is a shape that encloses 1009 pixels.

The shape must take the form of a single, closed, non-intersecting loop.

Input is a positive non-zero integer.

Each input must yield output that is unique — that is, each output must be unique from those generated using a lower input.

Victory is decided by the largest input limit:

Your submission's input limit is regarded as 1 less than the lowest input that gives non-unique or otherwise invalid output.
For instance, if valid and unique output is produced for an input of 1, 2 or 3 but not 4, your input limit is 3.

There is a 1009 byte limit on source code. If there is a draw the entry with the fewest bytes wins.

Restrictions and clarifications:

A shape's maximum size is 109 by 109 pixels. Size includes the line used to draw the shape.
A line is constant width.
The enclosed space must be entirely enclosed by the line - you can't use the boundary of the image file.
The enclosed 1009 pixels refers only to enclosed space. It does not include the line.
Output is an image.
There are no further graphical restrictions - e.g. on colour, line thickness etc.
An output's uniqueness refers only to the enclosed space. Changes to the line or other graphical changes are irrelevant if the enclosed space is not unique.
A translation of shape isn't unique. Rotations, reflections and any other transformations count as unique.
Output must be reproducible — the same input will always give the same output
There needn't be a relation between outputs, consecutive or otherwise.
Outside of a submission's 'input limit' there is no defined output.
No other input or fetching of external data is permitted.
A line must be continuous — i.e. pixels must touch (touching a corner counts).
A pixel is the smallest unit of 'drawing' used by your method of drawing, and won't necessarily correspond to a screen pixel.

Examples:

Here is an example of a valid shape:

The following shapes are invalid:

EDIT: Line touching:

Enclosed space must be continuous which is defined as pixels touching. Touching corners counts.

A line cannot enclose any space on its outer side. This image posted by @Sparr illustrates this point  - only the first shape on each row are valid:

The outer sides of a line may touch, but not in a way that encloses space.

Touching lines may not overlap - e.g. two touching 1 pixel thick lines would have a combined thickness of 2px, never 1px.

What about rotations of the same shape? Are they distinct?

If I take a bite out of the side of the shape, is it ok to have a foreground (black) line one pixel wide? Or does it have to be 3 pixels wide, so the incoming and outgoing line don't touch? or is it Ok to have it 2 pixels wide, so the incoming and outgoing line touch, but don't overlap?

Some more questions: 1. Can the border of the 109x109 image act as one boundary of the shape? 2. If the line thickness is up to me, can I just say it's 200 pixels, so that the shape is just white pixels on a black image? 3. Is the shape connected if its pixels only touch along a corner? 4. I'm not a big fan of the character limit. A lot of languages might use 3/4 of that just to set up the exact output specifications.

@MartinBüttner Rotations: They're distinct, yes, 1: No, the enclosed space must be enclosed by the shape's outline. 2: No, the shape would then count as larger than 109*109 3: Yes 4: You're probably right, I have increased it.

@steveverrill Sorry, I don't think I understand you. You may have 1 continuous line. Pixels touching by their corner's count as continuous.

Should we include some kind of proof that all inputs less than n yield distinct outputs? This could be difficult for example if you used the input number to seed a PRNG. I can think of solutions without random numbers, but I'm still curious if they must be 'provably unique'.

@stokastic I would like to see those kind of answers but I suppose you're right that scoring would be contentious. The score could be marked as provisional until it can be proven or disproven.

Question, how'd you get 1009?

Which of these shapes are valid and holeless? http://i.imgur.com/FSV0nHz.png

@Claudiu For the pixel count? I wanted it large enough for a decent number of solutions - in hindsight being smaller could have helped in scoring. Also it's a prime just to make things awkward. :)

@Sparr Sorry to be inconsistent - I've retracted my last reply after thinking more about the implications. Only 1 and 4 (the first on each row) are valid. Otherwise it's not possible to tell where enclosed space begins and ends. The rule is that the outer part of the line cannot touch in a way that encloses space, even with pixels touching corners. Very sorry if you had started on an answer based on my original reply.

@jsh change doesn't break my theoretical solution, just makes it run a lot slower

Python + Pycairo, 2100 shapes
Let's start with the obvious.

from cairo import *
from sys import argv

n = int(argv[1]) - 1

s = ImageSurface(FORMAT_ARGB32, 109, 109); c = Context(s)
c.set_antialias(ANTIALIAS_NONE); c.set_line_width(1); c.translate(54, 54)
def pixel(x, y): c.rectangle(x, y, 1, 1); c.fill()

W, H, R = 100, 10, 9
X1, Y1 = -W / 2 - 1, -H / 2 - 1
X2, Y2 = X1 + W + 1, Y1 + H + 1

pixel(X2 - 1, Y1)
c.move_to(X1, Y1 + 1); c.line_to(X1, Y2 + 1)
c.move_to(X2 + 1, Y1); c.line_to(X2 + 1, Y1 + R + 1);
c.move_to(X2, Y1 + R + 1); c.line_to(X2, Y2 + 1)
c.stroke()

for i in xrange(W):
    offset = (n >> i) & 1
    for y in Y1, Y2: pixel(X1 + i, y + offset)

s.write_to_png("o.png")

Takes the number on the command line and writes o.png.

Very nice. Simple idea, well executed. Won't be the winning score, but sets a good bar for further entries.

... *2, as Rotations [...] count as unique.

@edc65: Actually *4, since it's not symmetric.

BBC Basic, score 10^288 (minus 1 if zero not counted)
Download interepreter at http://sourceforge.net/projects/napoleonbrandy/ (not my usual BBC basic interpreter, that one doesn't support long enough strings.)
To encode a lot of information, you need a lot of perimeter. That means a thin shape. I start with a vertical bar of 49 pixels at the left, and add ten tentacles of 96 pixels to it. Each tentacle can encode 96 bits in a similar manner to @ell's solution, a total of 960 bits.
As BBC Basic cannot handle numbers that large, a number of up to 288 decimal digits is input as a string, and each set of 3 decimal digits is converted to a 10-bit binary number. Each bit is then used to wiggle one of the tentacles up by one pixel if it is a 1 (but not if it is a 0.) The program can handle up to 288/3=96 such sets of 3 digits
    1MODE1:VDU19,0,7;0;19,15,0;0;               :REM select an appropriate screen mode and change to black drawing on white background
   10INPUT a$
   20a$=STRING$(288-LEN(a$)," ")+a$             :REM pad input up to 288 characters with leading spaces
   50RECTANGLE0,0,8,200                         :REM draw a rectangle at the left, enclosing 49 pixels
   60FOR n=0 TO 95
   70  b=VAL(MID$(a$,n*3+1,3))                  :REM extract 3 characters from a$ and convert to number
   80  FOR m=0 TO 9                             :REM plot the ten tentacles
   90    PLOT71,n*4+8,m*20+8+(b/2^m AND 1)*4    :REM plot (absolute coordinates) a background colour pixel for tentacle m at horizontal distance n
  100    POINT BY 0,-4                          :REM offsetting vertically by 1 pixel according to the relevant bit of b
  110    POINT BY 4,4
  120    POINT BY -4,4                          :REM then plot foreground colour pixels (relative coordinates) above, below and to the right.
  130  NEXT
  140NEXT

Output
A typical output for a 288-digit number. Note that 999 is 1111100111 in binary. You can see how the sets of 9 digits cause the tentacles to undulate.

Technicalities
A.The answer to Martin's point 3 "is the shape connected if its pixel's touch only along a corner?" was "yes" so I understand my answer complies. Nevertheless, if you alternate (for example) 999's and 000's in every row, it looks very busy.
B. If we view this as a rectangle with bites taken out of the side, you can see that I allowed three pixels between each pair of adjacent tentacles, to ensure that the black line round the outside never touches itself. There is no specific rule on this (I hope my reason for asking is clearer in the light of my answer.) If the line is allowed to touch itself on the OUTSIDE of the shape, I could move the tentacles together and use less pixels for the vertical bar (and so make the tentacles a bit longer.) It would, however become very confusing to determine by eye whether a pixel was inside or outside the shape, so I think my interpretation that the outside of the black line should never touch itself is best.
C. BBC basic in this screen mode treats a 2x2 square of screen pixels as a single pixel. I've left this as it is, because it helps viewing if the shape is not too tiny. Each one of these BBC basic pixels is considered as a box of 4x4 logical units. From the start, the developers of BBC basic had the foresight to realise that one day screen resolutions would increase, so they made the logical resolution higher than the physical resolution.

A: The answer remains "yes", although I see now it is a bit odd. B. I see your point now and have made an edit to clarify, sorry for the confusion.

C: That's not a problem. A pixel is now defined as the smallest unit of drawing used.

Mathematica, 496 bytes, Score: large-ish (>1157)
The lower bound I've got there is ridiculously low, but I haven't found a better way than brute force to check yet.
SeedRandom@Input[];
g = 0 &~Array~{109, 109};
g[[2, 2]] = 1;
h = {{2, 2}};
For[n = 1, n < 1009,
  c = RandomChoice@h;
  d = RandomChoice[m = {{1, 0}, {0, 1}}];
  If[FreeQ[e = c + d, 1 | 109] &&
    Count[g[[2 ;; e[[1]], 2 ;; e[[2]]]], 0, 2] == 1,
   ++n;
   h~AppendTo~e;
   g[[## & @@ e]] = 1
   ];
  ];
(
    c = #;
    If[e = c + #; g[[## & @@ e]] < 1,
       g[[## & @@ e]] = 2
       ] & /@ Join @@ {m, -m}) & /@ h;
ArrayPlot[g, ImageSize -> 109, PixelConstrained -> True,
 Frame -> 0 > 1]

I haven't golfed this yet, because there was no need to. I'll do that once someone proves they are actually tying with me.
The algorithm is basically doing a flood-fill from the top-left corner of the 109x109 image (offset by one pixel to allow for the line) and when I've flooded 1009 cells, I stop and mark the border. You said colours are up to us, so the background is white, the line is black and the interior is grey (I can remove the gray for a handful of characters if necessary).
The flood fill is quite constrained, but that ensures that I don't have to worry about about holes. Relaxing these constraints will probably dramatically increase my (yet unknown) score.
I'll try to put some lower bounds on the score now.

Are you able to provide a CDF file so I can try this out?

@jsh Try this

I think all solutions that depend on random numbers will require a brute-force to validate. I'm not sure if you're doing a pixel by pixel check, but you could try saving each output to monochromatic bitmap (small filesize) and comparing the hashes. I imagine that's as fast as you'll get for image comparisons.

@stokastic I'm currently building a very naive hash (sum of all pixel coordinates), and then I'm checking the colliding bins in detail. The problem is, no matter how sophisticated an approach I use for collision checking, the generation method is so slow, that I won't even be able to solve more than a few 10k or 100k seeds in a reasonable amount of time. There are several ways to considerably speed up the algorithm though, I think, so I might look into that at some point.

@MartinBüttner You probably tested it already (or mathematica doesn't support it), but a straight up file-hash might be quicker. Just a suggestion if you haven't tried that.

@stokastic I'm not even generating files, but I'm sure there's some way to hash the resulting array even before plotting. But as I said, that's not the limiting factor at the moment, but the very naive way to flood fill which can take a lot of failed attempts before 1009 pixels are filled.

Python 2, Score > 10^395
It is extremely slow, and I haven't actually managed to get any result other than n=0, but if you want to test it lower SIZE (the number of pixels) and BOUND the maximum side length of the bounding square and you should be able to get plenty of results. It was very difficult to try and calculate how many it would produce; I am fairly confident that the lower bound I give is accurate, but I suspect the actual count to be significantly larger, and I may try to improve on it later.
import sys
import pygame
sys.setrecursionlimit(1100)

def low(s):
    return min(sum(e[1] for e in s[:i+1]) for i in range(len(s)))
def high(s):
    return max(sum(e[1] for e in s[:i+1])+s[i][0] for i in range(len(s)))

BOUND = 109
SIZE = 1009

def gen(n,t=0):
    if n <= (BOUND-t)*BOUND:
        for i in range(1,min(n,BOUND)):
            for r in gen(n-i,t+1):
                a,b=r[0]
                for x in range(max(1-a,high(r)-low(r)-BOUND),i):
                    yield [(i,0),(a,x)]+r[1:]
        yield [(n,0)]

def create(n):
    g=gen(SIZE)
    for i in range(n+1):shape=g.next()
    s=pygame.Surface((BOUND+2,BOUND+2))
    l=low(shape);x=0
    for y,(t,o) in enumerate(shape):
        x+=o;pygame.draw.line(s,(255,255,255),(x-l+1,y+1),(x-l+t,y+1))
    out=[]
    for x in range(BOUND+2):
        for y in range(BOUND+2):
            if all((0,0,0)==s.get_at((x+dx,y+dy))for dx,dy in[(-1,0),(1,0),(0,-1),(0,1)]if 0<=x+dx<BOUND+2 and 0<=y+dy<BOUND+2):
                out.append((x,y))
    for x,y in out:
        s.set_at((x,y),(255,255,255))
    pygame.image.save(s,"image.png")

Can you give the image for n=0? And also can you explain how you achieve 10^395?