text:
Counting Quipu: Base 10 in the New World
Quipus are an ancient device used by the Inca in the Precolumbian era to record numbers in a base ten positional system of knots on a cord, which works as follows:

Each cluster of knots is a digit, and there are three main types of knots: simple overhand knots; "long knots", consisting of an overhand knot with one or more additional turns; and figure-eight knots.

Powers of ten are shown by position along the string, and this position is aligned between successive strands.
Digits in positions for 10 and higher powers are represented by clusters of simple knots (e.g., 40 is four simple knots in a row in the "tens" position).
Digits in the "ones" position are represented by long knots (e.g., 4 is a knot with four turns). Because of the way the knots are tied, the digit 1 cannot be shown this way and is represented in this position by a figure-of-eight knot.
Zero is represented by the absence of a knot in the appropriate position.

Details
For this challenge, each strand of a quipu represents a single number (though, as the Wikipedia article states, you can represent many numbers on one strand, in this challenge, we shall not).
Knots
Each knot will be represented by a single ASCII character.

. represents a simple knot
: represents a one turn of a long knot
8 represents a figure-eight knot
| represents the absence of a knot as well as a delimiter between the digits.

Constructing Quipus
Quipu are constructed following these rules.

Strands run top to bottom in descending order of position (as in, the units digit will be at the bottom end of a strand). Digits along a strand are separated by the character (|).
The power of 10 a digit represents is determined by its position along the strand in the same way a digit's power of 10 would be calculated using its index in a number with our number system. That is, 24 with a 2 in the tens place and a 4 in the units place, will be represented by two knots, a delimiter (|), then four knots.
Digits in the same position are aligned towards the bottom of the strand. If one digit in a position will have less knots than other digits of other numbers in the same position, the absence of those knots is represented by (|).
Consecutive simple knots (.) represent a value in their position.
Every digit is represented by at least 1 character. When a digits value is 0 for all numbers in a quipu, it is represented by the absence of a knot (|).
The units place is treated specially. A one in the units place is represented by a figure-eight knot (8). A value of two or more in the units place is represented by consecutive long knots (:).
When the units digit is 0 for all numbers in a quipu the absence of a knot is not printed but, the trailing delimiter for the tens digit is preserved.
There is no delimiter following the units digit.

Rules

Input will consist of a non-empty list of non-negative integers that may be received through any of the default input methods. You may assume that these integers are all less than or equal to 2147483647 or 2^31-1. While the test cases are space-delimited, your input format can separate inputs in any way that is convenient for your language, whether that be comma-separated, newline-separated, in an array, and so on.
Output consists of a single Quipu constructed according to the rules described above. Output may be given through any of the default output methods.
Your code should be a program or a function, though it does not need to be a named function.
Knots take some time to tie so to save time, your code as short as possible.

As always, if the problem is unclear, please let me know. Good luck and good golfing!
Examples
Input:
5 3 1 0

Output:
:|||
:|||
::||
::||
::8|

Input:
50 30 10 0

Output:
.|||
.|||
..||
..||
...|
||||

Input:
330

Output:
.
.
.
|
.
.
.
|

Input:
204 1

Output:
.|
.|
||
||
||
:|
:|
:|
:8

Input:
201 0 100 222

Output:
.||.
.|..
||||
|||.
|||.
||||
|||:
8||:

Input:
1073741823 2147483647

Output:
|.
..
||
|.
||
.|
.|
.|
..
..
..
..
||
|.
|.
|.
|.
..
..
..
||
.|
.|
.|
..
..
..
..
||
|.
|.
|.
|.
..
..
..
..
||
|.
|.
..
||
.|
.|
..
..
..
..
..
..
||
|.
|.
..
..
||
|:
|:
|:
|:
::
::
::

Input:
0

Output:
|

Longer test cases
Further Reading

Ancientscripts: Quipu
The Quipu, Pre-Inca Data Structure

A related challenge on Maya numbers

Pyth, 64 bytes
=QjRTQjCmj\|+:R"[8:]"\.PdedCmm+*\|-h.MZdk*?tk\:\8kdC.[L0h.MZlMQQ

Try it online!
How it works
=QjRTQ   Converts each number in input to decimal (as a list)
         123 becomes [1,2,3]

----

jCmj\|+:R"[8:]"\.PdedCmm+*\|-h.MZdk*?tk\:\8kdC.[L0h.MZlMQQ

                                              .[L0       Q  0-leftpad each #
                                                  h.MZlMQ   (max length) times

                                             C              transpose

                      mm                    d    for each digit:
                        +                        [convert to] sum of
                         *\|                     "|" repeated
                            -                    the difference of
                             h.MZd               maximum digit in same row
                                  k              and itself.. that many times
                                   *?tk\:\8      and (digit > 1 then ":" or "8") repeated
                                           k     itself many times

the list:
[11,23,52]
->[[1,1],[2,3],[5,2]]
->[[1,2,5],[1,3,2]]
->[["||||8","|||::",":::::"],["||8",":::","|::"]]

                     C      transpose

->[["||||8","||8"],["|||::",":::"],[":::::","|::"]]

  m                          for each number
      +                      [convert to] sum of
                 Pd          every element but the last
       :R"[8:]"\.            with "8" and ":" replaced by "."
                   ed        and the last element
   j\|                       joined with "|"

  C                          transpose
 j                           join (with newlines)

This is an excellent answer except for one problem. The final knot is not always a figure-eight knot 8. In fact, it's only an 8 knot when last digit is a 1 (see rule 6). You're converting all the final knots and that doesn't match the spec. Also, your Try It Online! link has different code from that which is posted here, apparently

Unreadable, 3183 3001 bytes
This was a fun challenge to work on, on and off, in between Christmas celebrations. Thank you for posting! Golfing this was interesting because the specification is full of exceptions and special cases, which required lots of if conditions. Also, while I didn’t need to convert to and from decimal this time, I did need a “max” function of sorts to determine the largest number of digits in each number and the largest value of the digits in each place.
The first version of this was 4844 bytes, just to give you an idea of how much I golfed this.
The program expects the input as a comma-separated list of integers. No spaces or newlines. Using those will produce undefined behavior.

'""""""'""'""'""'""'""'"""'""""""'"""'""'""'""'""'""'""'""'""'""'""'""""""'""'""'""'""'""'""'"""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""""""'""""""""'"""'""'""'""'""'""'""""""'""'"""'""'""'""'""'""'""'""'""'"""'"""""'""""""'"""'""""""""'"""""""'"""'""""""'""""""""'"""'""'""'"""""""'""""""""'"""'"""""'""'""""""'""'""'""'"""'""""""""""'""""'""""""'""'""'"""'"""""""'""'""'""'""'""'""'"""'"""""""""'""""""'""""""'""'"""'""'"""""""'""'"""'""'"""""'""""""'""'""'"""'""""""""'"""""""'""'""'"""'""""""'""'""'""'"""'""""""""'"""""""'""'""'""'"""'""""""'""""""'"""'""""""""'"""""""'"""'"""'""""""'"""'""""""""'"""'""""""'""'""'"""'"""""'"""""""'"""""""'"""'""""""'"""'""""""""'"""""""'"""'"""""'""""""'"""'""'"""""""'"""'""""'""""""'""'""'""'"""'""""""""'"""'"""""'""""""""'""""""'"""""""'"""'""'"""""""'"""""""'"""'"""""""""'"""""""""'"""""""'"""""""'"""'"""'"""""""""'""'"""""""'"""'"""'""""""""'"""'""""'""""'""""""'""'"""'""'""'""'""'""'""'""'""'"""'"""""'"""""""'""""""'""'"""'""'"""""""'""'"""'""""'""""'"""""'""""""'""'""'""'""'""'""'""'"""'""""""'""'""'""'""'"""'"""""""'""""""'""'"""'""'"""""""'""'"""'"""'"""""'"""""""'""""""'""'"""'""""""""'"""""""'""'"""'"""""""""'""""""""'"""""""'""""""'""'""'""'""'""'""'""'"""'""""""""'"""""""'""'""'""'""'""'""'""'"""'"""""""""'""""""""'""""""""'"""""""'"""""""'"""'"""""""""'"""""""'""'""'""'"""'""""""'""'""'""'""'"""'"'"""""""""'""'"""""""'"""""""'""'"""'"""""""""'""'""'"""""""'"""""""'""'"""'""""'""""""'"""""""'""'"""'"""""""""'"""""""""'""'"""""""'"""'"""'"""""""""'""'""'"""""""'"""""""'"""'"""'"""""""""'""'""'""'"""""""'"""""""'""'"""'"""'""""""""'"""'""'"""""""'"""""""'""'"""'""""""""'""""""""'"""'"""""""'""""""""'"""'"""""""""'"""""""'"""""""'"""'"""""""""'""'"""""""'"""'"""""""'""'""'""'""'""'""'"""'""'""'"""""""'""'""'""'""'""'"""'"""""""'""""""""'"""'"""""""'""'""'""'""'""'"""'""""'"""""""""'"""""""""'""'"""""'"""""""'""""""'""'""'"""'""""""""'"""""""'""'""'"""'""""""'"""""""'""'"""'""""""""'"""""""'"""""""'""'"""'"""'"""""""""'"""""""'""'""'""'""'""'"""""""'""'""'"""'"""'"""""""""'""'"""""""'"""'"""'""""""""'"""'""""""'"""""""'""'"""'""""""""'"""""""'"""""""'""'"""'"""'"""""'"""""""'""""""'""'""'"""'""'"""""""'""'""'"""'"""'""""'""""'"""""'""""""'"""""""'""'"""'""""""""'"""""""'"""""""'""'"""'""""""'""""""'""'""'"""'""""""""'"""""""'""'""'"""'"""'"""""'"""""""'""""""'""'""'"""'""'"""""""'""'""'"""'""""""'"""""""'""'"""'""'"""""""'"""""""'""'"""'"""""""""'""'"""""""'"""'""""""'""""""""'""""""""'""""""""'""""""""'"""""""'""'""'"""'"""'"""'"""'"""""""""'"""""'"""""""'""""""'""'"""'""'"""""""'""'"""'"""""""'""'""'""'""'"""'"""'"""""""""'"""""""'""'""'""'"""'"'"""""""'""""""""'"""'"""'"""""""""'""""""""'""""""""'""""""""'"""""""'"""""""'"""'"""""""""'"""""""'""'""'""'"""'"'""'""'""'""'""'""'""'""'""'"""'"""'""""""'"""""""'"""'""""""""'""""""'""'""'""'"""'"""""'"""""""'""""""'""'""'"""'""""""""'"""""""'""'""'"""'""""""'"""""""'"""'""""""""'"""""""'"""""""'"""'"""

Explanation
I’m going to walk you through how the program works by showing you how it processes the specific input 202,100,1.
In the beginning, we construct a few values that we will need later — mostly the ASCII codes of the characters we will output.

As you can see, '8' and '.' are already available. '|', however, is really 124, not 14. We use a while loop to add twice the temporary value in slot #1 onto it to get 124 (which is 14 + 55×2, because the while loop runs for 56−1 = 55 iterations). This saves some bytes because large integer literals like 124 are really long. In the following diagram, I show the location of every variable the program uses.

Next, we want to input all the characters and store them on the tape starting at cell #12 (p is the running pointer for this). At the same time, we want to know how long the longest number is (how many digits). To achieve this, we keep a running total in unary going leftwards starting at cell #−1 (we use q as the running pointer). After the first input number (202), the tape now looks like this:

You will have noticed that the numbers are off by 4. Well, when we first input them, they are their ASCII values, so they’re “off” by 48 and the comma is 44. For each character, we copy the 46 from '.' into r and then subtract it with a while loop (which subtracts 45) and then we add 1. We do that so that the comma (our separator) is 0, so we can use a conditional to recognize it.
Also, you will have noticed that we leave cell #11 at 0. We need that to recognize the boundary of the first number.
The next character will be a comma, so we store a 0 in #15, but of course this time we don’t advance q. Instead, we set q back to 0 and start “overwriting” the 1s we’ve already placed.
After all the remaining characters are processed, we get this:

As you can see, the 1s written by q now indicate (in unary) the length of the longest number.
We now use a while loop to move q to the very left, and then place another pointer there which I will call r2. The purpose of r2 will become clear later.

At this point, let me clarify the terminology that I will use throughout this.

By number, I mean one of the input numbers that are separated by commas. In our example, they are 202, 100 and 1.
By digit, I mean a single digit in a specific one of the numbers. The first number has 3 digits.
By place, I mean the ones place, tens place, hundreds place, etc. So if I say “the digits in the current place”, and the current place is the ones place, those digits are 2, 0, and 1 in that order.

Now back to our regular programming. The entire rest of the program is a big loop that moves q forward until it reaches cell #0. Each of the cells along the way represents a place, with the ones place on the far right, and q will start at the most significant. In our example, that is the hundreds place.
We proceed by incrementing the cell q points at (that is, *q).

We are now at “stage 2” for the hundreds place. In this stage, we will find out what the largest digit is among all the digits in the hundreds place. We use the same unary counting trick for this, except this time the pointer is called r and the pointer r2 marks its starting position to which we need to reset it every time we move on to the next number.
Let’s start with the first number. We begin by setting p to 11 (the hard-coded starting position of all the numbers). We then use a while loop to find the end of the number and set p2 there to mark the position. At the same time, we also set q2 to 0:

Don’t be distracted by the fact that q2 is pointing into the vars. We don’t have a padding of a blank cell there because we can detect cell #0 simply because it’s number zero.
Next, we go through the current number by decrementing p and q2 together until *p is zero. At each place, the value of *q2 tells us what we need to do. 1 means “do nothing”, so we keep going. Eventually we encounter the 2 in cell #−3. Every time *q2 is not equal to 1, q2 is always equal to q.

As I already stated, stage 2 is “determine the largest digit in this place”. So we set r to r2, use a while loop to decrement *p and move r leftwards and fill the tape with 1s, and then use another while loop to move r back to the right and increment *p again to restore the value. Remember that every while loop runs for one fewer iteration than the value we use it on; because of this, the number of 1s written will be 3 more (rather than 4 more) than the digit value, and the final value stored back in *p will be 2 more. Thus, this has effectively decremented *p by 2.
After that, we set p to the value of p2 and then we do all that again. For the second time, set q2 to 0, find the end of the number by moving p to the right, and then go through the digits of this number by decrementing p and q2 together. Once again we will encounter the 2 in cell #−3 and write that many 1s left of *r.
In the case of the third number, we end up doing nothing because it doesn’t have a hundreds place (so q2 never reaches q), but that’s OK because that doesn’t affect the calculation of the maximum digit value.

We also set the cell *(r − 4), which I’ve marked with an unlabeled arrow here, to 1 (even though it’s already at 1). I’m not going to tell you why yet, but maybe you’ve already guessed?
The next increment of *q takes us to stage 3, which is “subtract the maximum digit from all digits in the current place”. As before, we reset p to 11 and q2 to 0 and then go through all the numbers just like we did in the previous stage; except this time, *q = 3 instead of 2. Every time q2 meets q and p is in a hundreds place, we use a while loop to decrement *p as many times as there are 1s in the block left of *r2 (5 in our example) by using r as a running pointer. We actually decrement it once more than that so that the largest digit ends up at −2, for a reason that will become clear later:

After we’ve processed all the numbers, we are now at the end of stage 3. Here we perform two singular things.

First, we also subtract the size of the r-block (plus 1) from *q, but using the r2 pointer, which leaves it on the left. *q becomes negative this way. In our case, the r-block has five 1s, so *q becomes −3.
Second, we set a variable out to a non-zero value to indicate that we are now entering the output stage. (Technically, the fact that *q is negative already indicates the output stage, but this is too difficult to check for, hence the extra variable.)

You now understand that we keep going through the numbers, find the current place (indicated by the non-1 value of *q) within each number, and do something depending on the value of *q. We see that *q is first incremented to 2 (= calculate maximum digit value), then 3 (subtract maximum digit value from every digit in this place) and then we subtract from it to make it negative. From there, it will continue to go up until it reaches 1, thus restoring the value that means “do nothing”. At that point, we move on to the next place.
Now, when *q is negative, we’re outputting. *q is at exactly the right value so that we will output the right number of rows of characters before it reaches 1; if the largest digit is 2, we need to output 3 rows. Let’s see what happens at each value of *q:

*q = −2:

For the first number, *p is −2, which indicates that we need to output a '.' (dot) or a ':' (colon). We decide which by looking at q: if it’s −1, we’re in the ones place, so output a ':' (which we calculate as '8'+2), otherwise a '.'.
For the second number, *p is −3. Anything that is not −2 means we output a '|' (pipe) and then increment the value. This way it will reach −2 in the right place and then we output '.'s/':'s for the rest of that digit.
In each case, we also set a variable pd to 0 before we process the number, and set pd (= “printed”) to a non-zero value to indicate that we have printed a character.
For the third number, no processing occurs because the third number does not have a hundreds place. In this case, pd will still be 0 after processing the number, indicating that we still need to output a '|' (but only if out is non-zero, because otherwise we’re still in stage 2 or 3).
After processing all numbers, if out is non-zero, output a newline. Note that we need the out variable so that we don’t output the newline in stage 2 or 3.

*q = −1: Same as before, except that *p is −2 for both the first two numbers, so both output a '.' (and the third outputs a '|' as before).
*q = 0: When *q is 0, this means “do nothing if we’re in the ones place, otherwise output a row of '|'s regardless of *p”. This way we get the padding between the digits.

Now we increment q to move on to the next place, the tens place, and increment *q there. At the beginning of Stage 2, the tape looks like this:

Then we perform Stage 2 just as before. Remember this effectively subtracts 2 from every digit in this place and also leaves a unary number left of *r2 indicating the maximum digit. We leave the previous unary number alone and just keep extending the tape to the left; it would only cost unnecessary extra code to “clean up”. When we’re done and we increment *q, at the start of Stage 3 the tape is now:

Actually, this is a lie. Remember earlier where I said we set *(r − 4) to 1 and I didn’t tell you why? Now I’ll tell you why. It’s for cases like this one, where the largest digit is in fact 0, meaning all the digits in this place are 0. Setting *(r − 4), indicated by the unlabeled arrow above, to 1 extends the unary number by 1, but only in this special case. This way we pretend as if the largest digit was 1, which means we will output one extra row.
After Stage 3 (subtract maximum digit from all digits in the current place), including the extra step that makes *q negative, the tape looks like this. Last time the biggest digit was represented by −2 in the *p block, but this time they’re all −3 because they’re all actually zeroes but we’re pretending as if the maximum digit was a 1.

Now let’s see what happens as *q progresses towards 1:

When *q = −1, the *p values are all −3, which means we output '|'s and increment them.
When *q = 0, we output '|' because that’s what we always do when *q = 0, regardless of *p.

Thus, we get two rows of pipes.
Finally, we move *q to the one’s place. This one gets interesting because we need to output ':'s if the actual digit is anything but 1, but an '8' if it’s 1. Let’s see how the program proceeds. First, we increment *q to initiate Stage 2:

After Stage 2 (“calculate maximum digit value”), we’re left with this:

After Stage 3 (“subtract maximum digit value from all digits in current place”) the tape looks like this:

Now let’s go through each iteration of *q in turn:

*q = −2:

First number: already at −2, so output a ':' (rather than a '.' because q = −1).
Second number: at −4, so output a '|' and increment.
Third number: at −3, so output a '|'. However, this time, instead of incrementing, a special case triggers. Only if we’re outputting the last place (q = −1), and we’re in the second-last row for that (*q = −2), and the digit is actually a 1 (*p = −3), then instead of incrementing it to −2, we set it to −1. In other words, we use −1 as a special value to indicate that in the next iteration, we will need to output '8' instead of ':'.

*q = −1:

First number: already at −2, so output a ':'.
Second number: at −3, so output a '|'. The special condition does not trigger because *q is no longer −2. Therefore, increment.
Third number: at −1, so output '8'.

*q = 0: Ordinarily, we would output the padding row of '|'s here, but in the special case where we’re in the ones place (q = −1), we skip that.

After this, q is incremented to 0 and the big while loop ends.
Now you know how an input like 202,100,1 works. However, there’s one more special case that we still haven’t covered. You may remember that while we were processing the last place, when *p was −3 we set it to −1 for the 1 (instead of incrementing it to −2) so that the next iteration would output an '8' instead. This only works because we have an iteration in which *p is −3 and we make a decision as to whether to increment it or set it to −1. We do not have such an iteration if all of the digits in the ones place are 0 or 1. In such a case all the *p values for the 1s would start out at −2; there is no opportunity to decide to set it to −1 rather than to increment it from −3. Because of this, there is another special-casing condition inside Stage 3 (“subtract maximum digit from every digit in the current place”). I claimed that after subtracting the maximum digit value from every digit (at which point the maximum digit is at −1), we just decrement it once more, but actually there’s a condition on that which goes as follows:
If the digit we’re looking at is equal to the maximum digit in this place (*p = −1), and this place is the ones place (q = −1), and the maximum digit is 1 (*(r + 5) = 0, i.e. the unary block at the very left is only 5 cells long), only then we leave *p at −1 to indicate that the only iteration of the output must output an '8'. In all other cases we decrement it once more.
Done. Happy new year!

Edit 1 (3183 → 3001): Some Happy New Year golfing! I managed to get rid of the variables p2 and r2 entirely! p now races back and forth to keep finding the beginning and end of numbers, but it seems to be shorter in code. I tried to get rid of q2 as well, but I couldn’t make the code shorter that way.
I also found a few more places where I could apply typical Unreadable golfing tricks like re-using the last value of a while loop. To give you an example, instead of
while *(++p) { 1 }         // just increment p until *p is 0; the 1 is a noop
if (pd) { x } else { y }   // where pd is a variable

I can save the '"""" (do the first, then the second) and the '""" (constant 1) by writing it in a way that is kind of like
if (while *(++p) { pd }) { x } else { y }

Of course, this only works if I know that the while loop will run for at least one iteration, but if it does, its return value is pd so I can use that as the condition for the if.

"Unreadable" is certainly an apt name...

-1 not enough explanation

Python 3, 624 598 595 574 561 535 532 527 525 426 345 328 324 294 288 286 283 280 267 265 255 251 245 238 235 234 230 228 236 244 bytes
z=input().split();v=max(map(len,z));d=''.join(i.zfill(v)for i in z);x=['']*len(z)
for k,c in enumerate(d):j=k%v;m=int(max(d[j::v]));c=int(c);x[k//v]+="|"*(m-c+(2>v)+(j>0)+0**(m+(j>v-2)))+":8."[(c<2)|-(j<v-1)]*c
for r in zip(*x):print(*r,sep='')

Try it online!
Well, since this question needed an answer, I have provided one here, where the input should be a space-separated string of numbers, such as "204 1". Boy, is it a long one. Any golfing suggestions (or better answers) are welcome.
Edit: Bytes saved by mixing tabs and spaces.
Edit: I saved a lot of bytes by changing how I obtained the digits of a number (make a list from the zero-padded string of the number, then in the body of the code, transpose to get hundreds digits, ten digits, etc.)
Edit: And I saved some more by incorporating that last :8 loop into the main quipu loop. Now if only I could figure out why b=d[j*v+i]==m(d[i::v]) won't work. Figured it out and the solution takes too many bytes. (Also the byte count dropped because somehow the tabs turned back into four spaces. It was probably the code block formatting on this site)
Edit: I reorganized how made the quipus. Now it creates one strand at a time, then transposes for printing.
Edit: Turned my answer back into a Python 3 program to save some more bytes.
Edit: I found a bug in my code that made it so that it was not printing zeroes in the middle of numbers correctly (see test case 204 1 above). In fixing this, I managed to golf it :)
Edit: I changed the printing to save 10 bytes. And I put all of the old byte counts back, just because.
Edit: Golfed the assignment of v using map for four bytes. Credit to CarpetPython, as I got the idea from their answer here.
Edit: Turned the middle "for loop inside a for loop", into just one for loop for six bytes.
Edit: Now using enumerate. No longer using l=len(z). Turned the ternary if-else into a list ternary. See below for details.
Edit: Sp3000 suggested an edit to print and an edit to the ternary condition that saved a byte each.
Edit: +6 bytes fixing a bug where the code did not follow rule 7. +8 more bytes in continuing to fix this bug. O bytes from more bug fixes.
Ungolfed:
s = input()
z = s.split()
v = max(map(len, z))                # the amount of digits of the largest number
d = ''.join(i.zfill(v) for i in z)  # pad zeroes until every number is the same length
                                     # then join the numbers into one string
x = ['']*len(z)                     # a list of strings for the output, one for each number

for k,c in enumerate(d):          # for every digit in every number
    i,j = divmod(k, v)            # i is the index of the number we're on
                                   # j is the index of the digit of the number we're on
    m = int(max(d[j::v]))         # the largest of all the digits in the j-th place
    c = int(c)                    # the digit in j-th place of the i-th number
    x[i] += "|"*(m-c+(j>0)+0**(m+(2>v)*(j>v-2)))
                                  # pad | to size m-c, until the knots are correctly spaced
                                  # add a | if all inputs are single-digit numbers
                                  # add a | if j>0, if it's not at the start, as delimiters
                                  # add a | if the maximum is 0 and it's *NOT* the ones digit
    x[i] += ":8."[(c<2)|-(j<v-1)] * c
    # this is essentially the following code
    # if j<v-1:
    #     x[i] += "."*c      # . knots if not in the units place
    # else:
    #     if c == 1:
    #         x[i] += "8"*c  # 8 knots for ones in the units place
    #     else:
    #         x[i] += ":"*c  # : knots for something else is in the units place

for r in zip(*x):       # transpose so all the rows (the quipu strings) now hang down
    print(*r, sep='')    # join the strings together at each knot
                         # and print each on a separate line

Is there anything specific to Python 3 here? If not, converting it to Python 2 could save quite a few bytes

@Cyoce Nothing too Python 3 specific. I just started in Python 3 because that's the version I have. I'll test a Python 2 version on ideone or something.

@Maltysen That doesn't work with an inputs that start with 0, such as 0 12 4.

You can save some bytes by alternating tabs and spaces for indentation in Python 2. I believe 1 tab character == 8 spaces according to python's indentation parser

for r in zip(*x):print(''.join(r)) -> print(''.join(r)for r in zip(*x))

Javascript (ES6) 750 744 690 604 498 346 245 234 bytes
I'm new to PPCG and thought I might give this one a try thinking it was rather simple. Boy was I wrong!! I've been working on it for a while and I have a lot of golfing to do...
Suggestions are encouraged! - although making sense of this won't be an easy task.
Outputs ropes when the input is an array of numbers (eg: [204, 1] ).
a=>(o=m=s="",l=a.map(n=>(s+="|",l=(n+"").length)>m?m=l:l),h=[],a=a.map((n,i)=>[..."0".repeat(m-l[i])+n].map((d,j)=>d<h[j]?d:h[j]=d)),h.map((n,i)=>{i?o+=s+`
`:0;for(j=n;j--;o+=`
`)a.map(d=>o+="|.:8"[d[i]-j<1?0:i<m-1?1:d[i]-1?2:3])}),o)

Explanation
a=>(

  o=m=s="",                      // m = max number of digits in a number, s = separator string
  l=a.map(n=>(                   // l = lengths of each number
      s+="|",                    // set the separator string
      l=(n+"").length                 // convert each number to a string
    )>m?m=l:l                    // get max length
  ),
  h=[],
  a=a.map((n,i)=>
    [..."0".repeat(m-l[i])+n]    // add leading 0s to make all same length
    .map((d,j)=>d<h[j]?d:h[j]=d) // set each digit of h to max
  ),

  h.map((n,i)=>{
    i?o+=s+`
`:0;
    for(j=n;j--;o+=`
`)
      a.map(d=>
        o+=
          "|.:8"[
            d[i]-j<1?0
            :i<m-1?1
            :d[i]-1?2:
            3
          ]
      )
  }),
  o
)

Example
Input: Array of numbers: [4,8,15,16,23,42]
Output:
|||||.
|||||.
||||..
||....
||||||
|:||||
|:||||
|:|:||
|:::||
::::||
:::::|
::::::
::::::

+1 impressive golfing.  Will you include an example with input and output?

@DavidC Thanks! And the example is included. Call it from the console and it returns a string. :)

Mathematica 436 453 357 352 347 bytes
t=Transpose;y=ConstantArray;a=Table;
g@j_:=(s=t[PadLeft[#,Max[Length/@i]]&/@(i=IntegerDigits@#)]&;p_~u~o_:=(m=Max@p;c=If[o==-2,":","."];w=If[o==-2,"8","."];p//.{0->a["|",Max@{1,m}],1->Join[a["|",{m-1}],{w}],n_/;MemberQ[2~Range~9,n]:>Join[y["|",m-n ],c~y~n]});t[Join@@@t@Join[u[#,0]&/@Most@#,u[#,-2]&/@{#[[-1]]}]]&[Riffle[(s@j),{a[0,Length@j]}]]//Grid)

The above

Breaks up each integer into a list of digits, using IntegerDigits; pads each number with zeros to the left (to ensure equal spacing); each input number, now decomposed into digits, corresponds to a row of an array; each column represents a place value. Array is transposed.
Replaces digits with a list of knots with padding. A slightly different pattern-matching routine is used for the units.

Example
g[Range[0, 50]]

Transpose@Join? That should be a t,right?

Yes. Thanks for catching this.

Space right before that.

C, 238 235 bytes
Relying heavily on the C preprocessor to make the code as short as possible. As a side effect, also makes it pretty much unreadable.
#define l strlen(a[i])
#define d l<k||a[i][l-k]-48
#define m(e) for(i=1;a[i];e<=r?i++:r++);
#define p(e) {m(!putchar(e?'|':k>1?46:d<2?56:58))puts("");}
k,r;main(int i,char**a){m(l)for(k=r,r=1;k;r=k>1){m(d)for(;r;r--)p(d<r)if(--k)p(1)}}

On Ubuntu 14.04, you can compile the code with a straightforward gcc quipu.c (please ignore the warnings). An example of running the executable:
$ ./a.out 1 2 3 2 1
||:||
|:::|
8:::8

Tested against all OP's test cases.
Ungolfed source code:
// Standard library; leaving out the includes still gives executable code despite the warnings.
#include <stdio.h>
#include <string.h>

// 4 preprocessor macros.
// Note: some of these actually make use of the fact that parentheses have been left out

// l: length of argument i
#define l     strlen(a[i])

// d: shorthand for a digit
#define d     l<k || a[i][l-k]-'0'

// m: loop across all arguments; calculates r as the maximum of expression e
#define m(e)  for (i=1; a[i]; e<=r ? i++ : r++);

// p: prints one line of output
// note: intentionally does not use the r++ code branch of m;
//       putchar always returns a non-zero number here, so !putchar is zero,
//       which is always <=r (because r is never negative)
// note: the semicolon after m(...) is redundant;
//       the definition of m already contains a semicolon
// note: puts("") outputs a newline
#define p(e)  { m(!putchar(e ? '|' : k > 1 ? '.' : d < 2 ? '8' : ':')); puts(""); }

// k: knot position; 1 for units, 2 for tens, 3 for hundreds...
int k;

// r: input and output value for m
// note: the first time we call m, we need r to be zero;
//       by defining it outside main, it is automatically initialized as such
int r;

// function main
// note: parameter i (normally named argc by convention) is not needed
//       (the last element of argv is known; it is followed by a NULL pointer)
//       but we cannot leave it out (otherwise we cannot access argv)
//       so it serves as a local variable (to loop through arguments; see m)
// note: parameter a (normally named argv by convention)
//       is the array of arguments (starting from index 1)
int main(int i, char **a)
{
    // Determine the longest argument; store its length in r.
    // This is the number of knot positions to consider.
    m(l)

    // Iterate k through the knot positions from top to bottom.
    // Note: k > 0 has been abbreviated to k.
    // Note: for each iteration, we also initialize r with either 0 or 1.
    //       0 = suppress printing when all knots are zero
    //       1 = always print, even when all knots are zero
    for (k = r, r = 1; k > 0; r = k > 1)
    {
        // Determine the highest digit at this knot position.
        // Note: due to the absence of parentheses, d mixes up with <=r into:
        // (l < k) || (a[i][l-k]-'0' <= r)
        m(d)

        // Count the digits down.
        for (; r; r--)
        {
            // Print a single line of output.
            // When d (the digit in the current strand) is less than the counter,
            // then print a '|', otherwise print a knot.
            p(d < r)
        }

        // Decrement k (go to next knot position).
        // If this was not the last iteration...
        if (--k > 0)
        {
            // Print separator line.
            p(1)
        }
    }

    // Return exit code zero; redundant.
    return 0;
}

Congratulations! As the shortest answer posted within the bounty period, you've received my bounty of +50 rep. Nice answer! :)

R - 446 444
I see there is no R solution yet, so here is one. The function takes a vector with integers.
function(x){r=nchar(max(x));c=length(x);m=matrix(0,r,c);for(i in 1:c){t=as.numeric(strsplit(as.character(x[i]),"")[[1]]);m[(r+1-length(t)):r,i]=t};Q=c();for(i in 1:r){d=m[i,];z=ifelse(max(d)>0,max(d),1);q=matrix("|",z,c);for(j in 1:c){v=m[i,j];if(i==r){if(v==1)q[z,j]=8;if(v>1)q[(z-v+1):z,j]=rep(":",v)};if(i<r){if(v>0)q[(z-v+1):z,j]=rep(".",v)}};if(i!=1&sum(d)>0)q=rbind(rep("|",c),q);Q=rbind(Q,q)};for(i in 1:nrow(Q))cat(Q[i,],sep="",fill=T)}

Ungolfed
# Some test data
test <- c(201, 0, 100, 222, 53)

# Define function
quipu <- function (x) {

    # Create matrix with a row for each digit and a column for each number
    r=nchar(max(x));c=length(x);m <- matrix(0,r,c)
    for(i in 1:c) {
        t=as.numeric(strsplit(as.character(x[i]),"")[[1]])
        m[(r+1-length(t)):r,i]=t
    }

    # Loop through each row (digit) starting at the top of the quipu
    Q=c() # Empty matrix to store quipu
    for(i in 1:r){

        d=m[i,]
        z=ifelse(max(d)>0,max(d),1)
        q=matrix("|",z,c)

        # Loop through each column (number in the vector) starting at the leftmost quipu
        for(j in 1:c){

            # The digit
            v=m[i,j]

            # If it is the last segment of the quipu
            if(i==r){
                if(v==1){q[z,j]=8} # If unit digit =1
                if(v>1){q[(z-v+1):z,j]=rep(":",v)} # If unit digit >1
            }

            # If it is not the last segment of the quipu
            if(i<r){
                if(v>0){q[(z-v+1):z,j]=rep(".",v)} # If non-unit digit >0
            }
        }

        # Add segment to Q
        if(i!=1 & sum(d)>0){q=rbind(rep("|",c),q)}
        Q=rbind(Q,q)
    }

    # Print quipu
    for(i in 1:nrow(Q)) {cat(Q[i,], sep="", fill=T)}
}

# Test
quipu(test)

Do you need if(v>0) in your if(i<r) clause? Does R accept a range like z+1:z when v==0? If so q[z+1:z,j] wouldn't be affected at all, I would think. Also, does R have an else keyword and some sort of else if keyword? If so, you'd be able to golf some of these conditionals.

if(v>0) is needed because if v=0, the index will be out of bounds (i.e., tries to get row nrow+1). R does have else, and I actually tried your suggestion and used else where possible, but it turned out to be the same number of bytes.

APL (Dyalog Unicode), 160 137 132 128 123 117 126 119 116 bytes
I sort of wrote this in a frenzy while unable to sleep tonight, so please forgive me if I skip the explanation, and miss any bugs or golfing opportunities. I'll take another look at this after I've gotten some sleep.
Edit: Turns out this doesn't for an input of just 0. Will fix soonest. -23 bytes from bug fixing! -5 bytes from removing no-longer-used variables. -4 bytes from using parts of the approach used in Leaky Nun's excellent Pyth answer (Sidenote: this answer is now exactly twice as long as that answer :D). -5 bytes from rearranging the result matrix mid-computation. -6 bytes from slimming down the generation of the result matrix even further. +9 bytes bug fixing. 0 bytes from more bug fixing. -7 bytes from rearranging how to handle the ones digit special case. -3 bytes from continued rearranging.
{⎕IO←0⋄m←⊖↓10⊥⍣¯1⊢1,⍵⋄1↓⊃⍪/⌽{w←1↓⊃m[⍵]⋄M+←1+0*((1≠≢m)∧⍵=0)+M←⌈/w⋄⊃,/⍵{M 1⍴((M-⍵)/'|'),⍵/'.'(':8'[1=⍵])[0=⍺]}¨w}¨⍳≢m}

Try it online!
Explanation
quipu←{
    ⎕IO←0         ⍝ Set to 0-indexing
    nums ← 1,⍵    ⍝ Append a 1 so that when converting in the next line,
                  ⍝ we always get a matrix, not a vector
    digit_list ← ⊖ ↓ 10⊥⍣¯1⊢ nums    ⍝ All the digits in each digit place, reversed

    ⍝ For each digit in each digit place, create knots
    1↓⊃⍪/⌽{    ⍝ After generating knots, these instructions clean up the result
        q ← ⍵
        w ← 1↓ ⊃ digit_list[⍵]    ⍝ 1↓ drops the 1 we appended before
        M +← 1+ 0* ((1 = ≢digit_list) ∧ (⍵ ≠ 0)) + M ← ⌈/w
        ⍝ M is the number of knot spaces (including delimiters) needed
        ⊃,/{     ⍝ ,/ concatenates the knots
            padding ← ((M-⍵) 1)⍴'|'
            knots ← ⍵ / ('.' (':8'[1=⍵]))[q=0]
            (M 1) ⍴ knots ⍪ padding   ⍝ Turns the knots into a column vector
                                      ⍝ of shape M by 1
        }¨w
    }¨⍳≢digit_list
}


text:
Hamilton is coming to town
It's almost Christmas, so Santa has to plan his route. You're helping him, for reasons unknown.
Santa needs help planning the route and wants you to give him a solution, but since you're all ungrateful and unwilling to give to the man who has given you so much, so have decided to give him a program with as few bytes as possible to accomplish the following.
The houses Santa needs to visit can be represented by coordinates on the Cartesian plane (the coordinates of the houses need not be integers, there cannot be more than 1 house at any point, and there is no house at the origin). These coordinates will be the input. Starting at the origin, Santa will visit each coordinate and then return to the origin.
Santa rides his sleigh at a constant one unit per second in a straight line between houses. However, when Santa crosses any lattice point (a point with integer x and y coordinates) he stops for one second to eat a cookie (the initial and final crossings of the origin do not count, though crossing it on the path between, say, (-1,-1) and (1,1) would). When he stops at a house, he spends five seconds to deliver a present (so he spends six seconds at houses on lattice points).
Write a program that takes as its input a set of coordinates and prints the smallest number of seconds Santa needs to deliver all of the presents to the houses and return to the origin, rounded to three digits. Take 25% off your code if it also prints any order of coordinates Santa visits that minimizes the time.

Test cases
(1,1) (2,4) (2,2)
==> 14.301
==> (Bonus) (1,1) (2,2) (2,4)

(3,4) (2,-1) (0,-3.5) (1,6)
==> 27.712
==> (Bonus) (0,-3.5) (2,-1) (3,4) (1,6)

This is code golf. Standard rules apply. Shortest code in bytes wins.

Note that this is a modification of the Travelling Salesman Problem, so your program does not need to terminate in any reasonable amount of time for an unreasonable number of inputs (this is a problem in O(n!) after all).

You DO realize that this is the Travelling Salesman Problem, right? None of these are going to be particularly fast.

@Deusovi I forgot to mention that at the end, thanks for the catch.

You you please provide some test cases?

How is this a duplicate? It adds the challenge of trying to find a path with the least lattice crossings.

I agree with @LegionMammal978. This provides an additional challenge, which I added BECAUSE of that other question.

@LegionMammal978, it doesn't. The optimum solution may not be the one with fewest lattice crossings. What it adds, which IMO is pretty borderline as a non-dupe difference, is the requirement to calculate the weights in the complete graph rather than taking them from input as in this question.

Clicked on the title expecting Hamilton. Was disappointed. ;P

I don't think your test cases are correct.  If Santa stops at each house for 5 seconds, it's impossible for him to visit three in less than 15 seconds.

Perl 6, 198 bytes (264 bytes - 25% bonus)
Managed to actually get this sucker into a Whatever block by inlining the helper functions from the original version.
*.permutations.map({([+] -1,5*@_,|(for (0,0),|@_ Z |@_,(0,0) ->((\i,\j),(\x,\y)){my ($s,\p)=0,i.Rat.nude[1]*j.Rat.nude[1]*abs(i -x).Rat.nude[0];(i+(x -i)*$_/p)%%1&&(j+(y -j)*$_/p)%%1&&$s++ for ^p;sqrt(abs(i -x)²+abs(j -y)²)+(p??$s!!abs(j.Int -y.Int))})),@_}).min

Try it online!
No doubt there are still a few little improvements that can be made.  Trickiest part was figuring out how to calculate the number of lattice points crossed.  The solution I went with uses the denominators of each X coordinate to calculate an iteration interval that is guaranteed to hit each whole number along with X axis, thus allowing a check for landing on a lattice point.  There is a catch, of course, that if there is no movement along X then the lattice points crossed will be the absolute value of the floor value of each Y coordinate.
This will be, nonetheless, very tricky for languages that don't have built in rationals, because of floating point errors (I can already see the .1 + .2 = .3 issue cropping up if any two X or Y coordinates are 10 apart).
Ungolfed version:
*                           #  Whatever block, takes a list of coordinates
.permutations.map({         #  Get all combinations and to each of them ...
 (                          #   Implicitly return a list consisting of
  [+]                       #    The sum of
   -1,                      #     -1 (to discount lattice +1 on return to origin)
   5*@_,                    #     5 * number of coordinates (or stops)
   |(for                    #     each value in the loop across
    (0,0),|@_ Z |@_,(0,0)   #      the coordinates (zipping with the origin
                            #        first/last for the return)
    ->((\i,\j),(\x,\y)) {   #      deconstructing into i,j,x,y
     my ($s,\p)=0,          #      set S (lattice stops) to 0
       i.Rat.nude[1]        #      set P (x check interval) to denominator of i
       *j.Rat.nude[1]       #       times denominator of p (psuedo lcm)
       *abs(i -x).Rat.nude[0]; #    times x-diff numerator (bc Rat simplification)
     (i+(x -i)*$_/p)%%1&&   #      check X is whole, if so,
      (j+(y -j)*$_/p)%%1&&  #       check Y is whole, if so,
      $s++                  #        increment S (trip crossed a lattice point)
     for ^p;                #      do the checks for 0 to P
     sqrt(                  #      implicitly return
      abs(i -x)²+abs(j -y)² #       the distance
     )+(p                   #        plus, if X values were different,
      ??$s                  #         S value, else
      !!abs(j.Int -y.Int)   #         Y difference = vertical lattice crossings
     )
    }
   )                        #
   ,@_)                     #   And the permutation
.min                        #  Find best (smallest) time

I'll probably add a more readable version because this golfing got unreadable fast.

source: Stack Exchange

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

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

sort: votes


text:
Chain reaction of bombs
Introduction:
Before the task, here is what every element does on the map:
Plain land (X): This does nothing.
Destroyed land (-): This is the same as plain land, but destroyed by a bomb.
The active bomb (!): On a map, this will destroy everything in a 3x3 square:
XXXXX                         XXXXX
XXXXX                         X---X
XX!XX     > will become >     X---X
XXXXX                         X---X
XXXXX                         XXXXX

The passive bomb (@): It does nothing, until it is detonated by another bomb. This also has a 3x3 square explosion radius:
XXXXX                         XXXXX
XXXXX                         XXXXX
XX@XX     > will become >     XX@XX (nothing happened)
XXXXX                         XXXXX
XXXXX                         XXXXX

But:
XXXXX                         XXXXX
XXXXX                         X---X
XX@XX     > will become >     ----X (both bombs have exploded)
X!XXX                         ----X
XXXXX                         ---XX

The nuke (~): It does nothing, until it is detonated by another bomb. The difference is that this bomb has a 5x5 square explosion radius:
XXXXX                         XXXXX
XXXXX                         XXXXX
XX~XX     > will become >     XX~XX (nothing happened)
XXXXX                         XXXXX
XXXXX                         XXXXX

But:
XXXXX                         -----
XXXXX                         -----
XX~XX     > will become >     ----- (both bombs have exploded)
X!XXX                         -----
XXXXX                         -----

The task

Given a 9x9 map, output the map after the chain reaction.
You may provide a function or a program.
This is code-golf, so the submission with the least amount of bytes wins!

Test cases
Test case 1 (3 steps):
XXXXXXXXX           XXXXXXXXX
----XXXXX           ----XXXXX
XXXX@XXXX           XXXX@XXXX
XXXXXXXX-           XXX---XX-
XXXX@XXXX     >     ------XXX
XXXXXXXX-           ------XX-
XX~XXXXXX           -----XXXX
X!XXXXXX-           -----XXX-
XXXXXXXXX           -----XXXX

Test case 2 (2 steps):
XXXXXXXXX           XXXXXXXXX
XXXXXXXXX           XXXXXXXXX
XX~XXXXXX           XX~XXXXXX
---------           ---------
XXXX!XXXX     >     XXX---XXX
XXXXXXXXX           XXX------
XXX@@X@!X           XXX@@----
XXXXXXXXX           XXXXX----
XXXXXXXXX           XXXXXXXXX

Test case 3 (2 steps):
XXXXXXXXX           XXXXXXXXX
XXXXXXXXX           XXXXXXXXX
XX~XXXXXX           XX~XXXXXX
XXXXXXXXX           XXX---XXX
XXXX!XXXX     >     XXX---XXX
XXXXXXXXX           XXX------
XXX@@X@!X           XXX@@----
XXXXXXXXX           XXXXX----
XXXXXXXXX           XXXXXXXXX

Test case 4 (1 step):
XXXXXXXXX           XXXXXXXXX
XXXX-XXXX           XXXX-XXXX
XXXXXXXXX           XXX---XXX
XX-X!X-XX           XX-----XX
XXXXXXXXX     >     XXX---XXX
XX-----XX           XX-----XX
XXXX-XXXX           XXXX-XXXX
XXXXXXXXX           XXXXXXXXX
XXXXXXXXX           XXXXXXXXX

Test case 5 (9 steps):
!XXXXXXXX           ---XXXXXX
X@XXXXXXX           ----XXXXX
XX@XXXXXX           -----XXXX
XXX@XXXXX           X-----XXX
XXXX@XXXX     >     XX-----XX
XXXXX@XXX           XXX-----X
XXXXXX@XX           XXXX-----
XXXXXXX@X           XXXXX----
XXXXXXXX@           XXXXXX---

Test case 6 (9 steps):
XX@@@XXXX           ------XXX
XXXXXXXXX           ------XXX
~XXXXXXXX           ---XXXXXX
XXXXXXXXX           ---XXXXXX
~XXXXXXXX     >     ---XXXXXX
XXXXXXXXX           ---XXXXXX
~XXXXXXXX           ---XXXXXX
@XXXXXXXX           ---XXXXXX
!XXXXXXXX           ---XXXXXX

Test case 7 (3 steps):
!XXXXXXXX           ---XXXXXX
X@XXXXXXX           ----XXXXX
XX@XXXXXX           ----XXXXX
XXXXXXXXX           X---X----
XXXXXX@@!     >     XXXXX----
XXXXXXXXX           X---X----
XX@XXXXXX           ----XXXXX
X@XXXXXXX           ----XXXXX
!XXXXXXXX           ---XXXXXX

My answer is significantly shorter than the accepted one.

May base part of a workshop on this challenge?

Matlab, 120 111 bytes
function f=c(f);c=@(x,i)conv2(x+0,ones(i),'s');a=c(f<34,3);for k=f;a=c(a&f<65,3)|a;a=c(a&f>99,5)|a;end;f(a)='-'

Convolution is the key to success.

The idea is following: Find the active bomb. Enlarge this area to a 3x3 square. Find new affected bombs, enlarge the correspoding areas to the corresponding size and add those to the previously destroyed area. Repeat this enough times (in my case as many times as we have input characters, just because that is the shortest variant) to be sure that we reached a stationary point (=no more exploding bombs). Then set all the destroyed area to - and display the result.
The input is assumed to be a matrix of characters, e.g.
['!XXXXXXXX';
'X@XXXXXXX';
'XX@XXXXXX';
'XXX@XXXXX';
'XXXX@XXXX';
'XXXXX@XXX';
'XXXXXX@XX';
'XXXXXXX@X';
'XXXXXXXX@'];

Retina, 188 168 154 152 bytes
Bytes counted as ISO 8859-1.
+Tm`@~X!:`!:\-`(.)?.?.(.?(?<1>.)?)(?<=(:|(?(1)_)!|^(?(5)_)(?<-5>.)*(:|(?(1)_)!)(?<1>.*¶)?.*¶(.)*.|(?=(.)*¶.*(?<1>¶.*)?(:|(?(1)_)!)(?<-6>.)*(?(6)_)$))\2)

Try it online!
This is more of a proof of concept. There is a horrible amount of duplication between bombs and nukes, which I'll try to get rid of before adding an explanation. Well, I got rid of that duplication but it increased the complexity significantly so it didn't actually result in huge savings...

APL (Dyalog), 56 chars or 62 bytes*
My colleague Marshall came up with an elegant solution, 21 characters shorter than mine:
{'-'@(({1∊⍵≥∘.⌈⍨5⍴1+4↑1}⌺5 5×∘(('X'≠⍵)+'~'=⍵))⍣≡'!'∘=)⍵}

Try it online!
{…} anonymous function where the argument is represented by ⍵
 '-'@(…)⍵ dash at the positions masked by the following tacit function:
  '!'∘= Boolean where exclamation point equals the argument
  (…)⍣≡ apply the following tacit function until nothing more changes:
   ×∘(…) multiply by the following constant:
    '~'=⍵ Boolean where tilde equals the original argument
    (…)+ to that, add:
     'X'≠⍵ Boolean where X is different from the original argument
   {…}⌺5 5 for each, apply the following function on the 5×5 area centered on it:
    4↑1 take the first four elements of one, padding with zeros [1,0,0,0]
    1+ add one [2,1,1,1]
    5⍴ reshape cyclically into length five [2,1,1,1,2]
    ∘.⌈⍨ maximum table with itself on both axes
    ⍵≥ Boolean where the corresponding neighbours are greater than or equal to that
    1∊ Boolean if any is true

* Just replace ⌺ with ⎕U233A  under Classic for single byte per character.

in the tio link, input (to the left of ">") is the same as output (to the right of ">"), is it supposed to look like that?

@ngn Nicely spotted. The Disp function could never have worked. Updated to be an operator. Thanks.

...and a question: does @ count as 1 byte in classic? my guess is yes

@ngn Yes.

here's an idea for 61 bytes: '-'@({i/⍨∨⌿↑(↓⌈/¨|⍵∘.-i)≤3|'X@~-'⍳a[⍵]}⍣≡('!'=,a)/i←,⍳⍴a)⊢a←⎕ (⎕io←0)

@ngn Hm, longer, but fewer bytes. Why don't you post it? Also, can't you use a fn right operand to the leftmost @?

'⍸'∊⎕av → huh!?

@ngn Let us continue this discussion in chat.

Java, 574 562 558 549 525 523 bytes
import java.util.*;interface B{static char[][]g=new char[9][9];static void d(int i,int j,int r){g[i][j]=45;for(int x=Math.max(i-r,0);x<Math.min(i+r+1,9);x++)for(int y=Math.max(j-r,0);y<Math.min(j+r+1,9);y++)if(g[x][y]==64){d(x,y,1);}else if(g[x][y]>99){d(x,y,2);}else g[x][y]=45;}static void main(String[]a){Scanner q=new Scanner(System.in);for(int i=0;i<9;i++){int j=0;for(char c:q.nextLine().toCharArray())g[i][j++]=c;}for(int j=0;j<9;j++)for(int k=0;k<9;k++)if(g[j][k]==33)d(j,k,1);for(char[]z:g)System.out.println(z);}}

I know it's been quite a while since you've posted this. But you can golf a few things: Both '-' can be 45. Both Math.max(...,0) can be ...>0?...:0 (same could be done with Math.min(...,9) but it's the exact same amount of bytes. for(int i=0;i<9;i++){int j=0;for(char c:q.nextLine().toCharArray())g[i][j++]=c;}for(int j=0;j<9;j++)for(int k=0;k<9;k++)if(g[j][k]==33)d(j,k,1); can be int i=0,j;for(;i<9;i++){j=0;for(char c:q.nextLine().toCharArray())g[i][j++]=c;}for(i=0;i<9;i++)for(j=0;j<9;j++)if(g[i][j]<34)d(i,j,1);. And maybe you could make a function out of it instead of program.

APL (Dyalog Classic), 61 bytes
'-'@({i/⍨∨⌿↑(↓⌈/¨|⍵∘.-i)≤3|'X@~-'⍳a[⍵]}⍣≡('!'=,a)/i←,⍳⍴a)⊢a←⎕

Try it online!
a←⎕ evaluate input and assign to a
i←,⍳⍴a the indices (pairs of coords) of all cells
('!'=,a)/ filter only the initially active bombs
{ }⍣≡ perform a transformation on the list until it stabilizes

'X@~-'⍳a[⍵] substitute 0 for X, 1 for @, etc, 4 for anything else (!)
3| mod 3 to get the "radius" of impact; it must be greater or equal to the...
(↓⌈/¨|⍵∘.-i)≤ ...Manhattan distances between cells in the list and all cells
i/⍨∨⌿↑ get bitmask of which cells are affected and select those from i

'-'@( )⊢a put - at those positions

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


text:
Parenthesize an expression
Recently I've been writing a new language, to avoid needing to handle order of operations, I simply parenthesize each expression properly to avoid this entirely.
Because parenthesis are at char-codes 40-41, your code will need to be as short as possible.

Examples
1+2*3
(1+(2*3))

2*(3+4)
(2*(3+4))

2*3/4+3
(((2*3)/4)+3)

342*32/8
((342*32)/8)

Rules
The only operations you'll need to handle are: * (multiplication), / (division), + (addition), and - (subtraction).

The order of operations is:

Parenthesis
Multiplication, Division
Adition, Subtraction

You should prefer to go left-right
The input numbers will always be positive integers (see bonuses)

Bonuses
-20% if you handle negation:
3+-5
(3+(-5))

-5% if you allow spaces to be placed inside the input:
3  + 4
(3+4)

-10% if you can handle decimals in the input:
1+.12
(1+.12)
1+0.21/3
(1+(0.21/3))

500 bounty: if you manage to write an answer in Unnamed/Blocks

And you want us to write the parser for you? :3

"Because parenthesis are at char codes 40-41, your code will need to be as short as possible." OK, now you're just being plain ridiculous. ;P

@ETHproductions I'll award a bounty (500?) if anyone manages to do that but I doubt it's possible because currently it can barely add numbers :/

Whoops, accidentally deleted my comment. Here it is for reference: "Do we get a bonus for answering in your new language?"

And this is easier than prefix (Polish) notation because?

Possible duplicate.

@flawr I saw that but it's very different in the fact that that question has you output all ways parenthesizing an expression. Here you have to take into account order of operations which I think is a significant difference as code can't be trivially modified for this challenge

Important test case: 1+2+3+4 (which certain solutions might parenthesise as ((1+2)+(3+4)))

About handling negation: 3 - - - - 6 => (3+6) or (3-(-(-(-6)))) ?

Is it ok to put parenthesis around each number? For example: ((3)+(4)) for 3+4 and ((1)+((2)*(3))) for 1+2*3?

The first paragraph gives some context, but you seem to have forgotten to give the specification. You've told us what you do: what do you want us to do? What input do we take? What processing do we perform on it?

Where can I find specification for Unnamed?

@ChristianIrwan there's not much documentation but there's an esolangs article here and you can look at the source code of the page and look for the
@Doᴡɴɢᴏᴀᴛ The esolang article doesn't have specification of command.

I don't read in Javascript.

@ChristianIrwan hmm, sorry about the lack of documentation, I don't even know how the language works anymore but basically is replaced with the input. This means your code is essentially1,1::0,0={JS_CODE}|; 0,0essentially sets the first output (Unnamed has 2D output).1,1sets an output to a 1*1 matrix. the|` is the Set command. I'll try to write up some more docs tonight,

The "Unnamed" link does not work.

Python, 153 * 0.9 = 137.7 bytes
def p(e):
 for o in"+-*/":
    for i,c in enumerate(e):
        if(c==o)*(0==sum([(d=="(")-(d==")")for d in e[:i]])):return"("+p(e[:i])+o+p(e[i+1:])+")"
 return e

This program handles decimal input.
The second line begins with a space, the second begins with a tab, the third with two tabs and the third with a space. This saved one byte. Here's a hexdump (xxdp p):
0000000: 6465 6620 7028 6529 3a0a 2066 6f72 206f  def p(e):. for o
0000010: 2069 6e22 2b2d 2a2f 223a 0a09 666f 7220   in"+-*/":..for
0000020: 692c 6320 696e 2065 6e75 6d65 7261 7465  i,c in enumerate
0000030: 2865 293a 0a09 0969 6628 633d 3d6f 292a  (e):...if(c==o)*
0000040: 2830 3d3d 7375 6d28 5b28 643d 3d22 2822  (0==sum([(d=="("
0000050: 292d 2864 3d3d 2229 2229 666f 7220 6420  )-(d==")")for d
0000060: 696e 2065 5b3a 695d 5d29 293a 7265 7475  in e[:i]])):retu
0000070: 726e 2228 222b 7028 655b 3a69 5d29 2b6f  rn"("+p(e[:i])+o
0000080: 2b70 2865 5b69 2b31 3a5d 292b 2229 220a  +p(e[i+1:])+")".
0000090: 2072 6574 7572 6e20 650a                  return e.

Here's a program I used for testing: (Save the program above as paren.py)
import paren

cases = {
        "2+3*4": "(2+(3*4))",
        "(2+3)*4": "((2+3)*4)",
        "1+2+3+4": "(1+(2+(3+4)))",
        "3/2+5": "((3/2)+5)",
        "1+2-3": "(1+(2-3))",
        "2-1+2": "((2-1)+2)",
        "3+-5": "(3+(-5))",
        "1+.12": "(1+.12)",
        "1+0.21/3": "(1+(0.21/3))",
}

for num, case in enumerate(cases):
    print "\n\n\033[1m\033[38;5;14mCase #%d: %s" % (num + 1, case)
    result = paren.p(case)
    print "\033[38;5;4mParenthesize returned: %s" % (result)
    solution = cases[case]
    if result == solution:
        print "\033[38;5;76mCorrect!"
    else:
        print "\033[38;5;9mNot correct!"

Make sure that your terminal uses the \033[38;5;<COL>m escape code for colors.

*fourth with a space?

This program does not prefer to go left-right. Try the test case 3 in the OP, your result is not correct. This can be a real issue for example with integer arithmetic: ((2*(3/4))+3) != (((2*3)/4)+3)

@user12365 Not using integer arithmetic (in C or C++ for example) 3/4 == 0, so ((2*(3/4))+3) is 3, while (((2*3)/4)+3) is 4

JavaScript (ES6) 179 (263 -20% -5% -10%)
(x,W=[],Q=['('],z=1,w=v='',h=p=>'*/+-))('.indexOf(p)|1,C=n=>{for(;h(q=Q.pop())<=h(n);)W[0]=`(${W[1]+q+W.shift()})`;z&&Q.push(q,n)})=>(x+')').replace(/[\d.]+|\S/g,t=>t>'('?t>')'?~h(t)?z?(w+='('+t,v+=')'):C(t,z=1):W=[w+t+v,...W,z=w=v='']:C(t,z=0):z=Q.push(t))&&W[0]

As the other two answers are currently both wrong, I'll post mine. It's a variation of the expression parser that I used here and here and somewhere else. Look there for more detailed algorithm explanations.
It's quite bulky but it should work.
Test snippet

f=(x,W=[],Q=['('],z=1,w=v='',h=p=>'*/+-))('.indexOf(p)|1,C=n=>{for(;h(q=Q.pop())<=h(n);)W[0]=`(${W[1]+q+W.shift()})`;z&&Q.push(q,n)})=>(x+')').replace(/[\d.]+|\S/g,t=>t>'('?t>')'?~h(t)?z?(w+='('+t,v+=')'):C(t,z=1):W=[w+t+v,...W,z=w=v='']:C(t,z=0):z=Q.push(t))&&W[0]

// More readable
x=(x,W=[],Q=['('],z=1,w=v='',
  h=p=>'*/+-))('.indexOf(p)|1,
  C=n=>{
    for(;h(q=Q.pop())<=h(n);)W[0]=`(${W[1]+q+W.shift()})`;
    z&&Q.push(q,n)
  }
)=>(
  (x+')')
  .replace(/[\d.]+|\S/g,t=>
       t>'('
       ?t>')'
       ?~h(t)
       ?z
       ?(w+='('+t,v+=')')
       :C(t,z=1)
       :W=[w+t+v,...W,z=w=v=''] // overfill W to save 2 chars ()
       :C(t,z=0)
       :z=Q.push(t)
  ),
  W[0]
)

console.log=(...x)=>O.textContent+=x.join` `+'\n'

// TEST
;[
  ['1+2*3','(1+(2*3))'],['2*(3+4)','(2*(3+4))'],['2*3/4+3','(((2*3)/4)+3)'],['342*32/8','((342*32)/8)'],
  ['3+-5','(3+(-5))'],['-3+-4*7','((-3)+((-4)*7))'], // bonus 20%
  ['3  + 4','(3+4)'], // bonus 5%
  ['1+.12','(1+.12)'],['1+0.21/3','(1+(0.21/3))'] // bonus 10%
].forEach(t=>{var k=t[1],i=t[0],r=f(i); console.log(i+' : '+r+(r==k? ' OK':' Fail expecting '+k))})

Python, 241 * 0.8 * 0.95 * 0.9 = 164.84 characters
I'm using the ast (Abstract Syntax Trees) library, and a homebrew string replacement dict. The string replacement costs a lot, but the bonus helps in keeping the score somewhat low. Maybe (the string replacement part) can be golfed further.
Note that this solution adds an extra set of parenthesis around each number, but I think that's within the spirit of the question
import ast;def p(e):
 r,s={"Module([":"",")])":"","Expr(":"","BinOp":"","Num":"",", Add(), ":"+",", Sub(), ":"-",", Div(), ":"/",", Mult(), ":"*"},ast.dump(ast.parse(e),annotate_fields=False)
 for f,t in r.iteritems():s=s.replace(f,t)
 return s

Test suite:
cases = {
    "2+3*4",
    "(2+3)*4",
    "1+2+3+4",
    "3/2+5",
    "1+2-3",
    "2-1+2",
    "3+-5",
    "1+.12",
    "1+0.21/3"
}

for num,case in enumerate(cases):
    result = p(case)
    print "Case {}: {:<16} evaluates to: {}".format(num+1,case,result)

Output of the test suite:
Case 1: 3+-5             evaluates to: ((3)+(-5))
Case 2: 3/2+5            evaluates to: (((3)/(2))+(5))
Case 3: 2+3*4            evaluates to: ((2)+((3)*(4)))
Case 4: 1+2+3+4          evaluates to: ((((1)+(2))+(3))+(4))
Case 5: 1+0.21/3         evaluates to: ((1)+((0.21)/(3)))
Case 6: (2+3)*4          evaluates to: (((2)+(3))*(4))
Case 7: 2-1+2            evaluates to: (((2)-(1))+(2))
Case 8: 1+.12            evaluates to: ((1)+(0.12))
Case 9: 1+2-3            evaluates to: (((1)+(2))-(3))

Missing import ast in your code

And that is not the right way to compund percent bonus. If you get a discount of 50% and on top of that another of 50%, your are not paying 0. Your score should be 157.32 (something more after adding the import line). That is a good score - I'll upvote if you make the fix

Good point. Added the import. 241 characters now. Not sure how to calculate the bonus though. If I understand your comment correctly, the order in which the bonus is subtracted matters...

The bonus is not subtracted (it's a multiplication) and the order does not matter. 241*(1-20%)(1-5%)(1-10%) => 2410.80.95*0.9 => 164.84

@edc65 Ah. Right. Wasn't thinking straight. Thanks.


text:
The Abelian Orders
Some background
In math, a group is a tuple \$(G, *)\$ where \$G\$ is a set and \$*\$ is an operation on \$G\$ such that for any two elements \$x, y \in G, x * y \in G\$.
For some \$x,y,z\in G\$, basic group axioms are as follows:

\$G\$ is closed under \$*\$, i.e. \$x * y \in G\$
The operation \$*\$ is associative, i.e. \$x * (y * z) = (x * y) * z\$
\$G\$ has an identity element, i.e. there exists \$e \in G\$ such that \$x * e = x\$ for all x
The operation \$*\$ is invertible, i.e. there exist \$a, b \in G\$ such that \$a * x = y\$ and \$y * b = x\$

Okay, so those are groups. Now we define an Abelian group as a group \$(G, *)\$ such that \$*\$ is a commutative operation. That is, \$x * y = y * x\$.
Last definition. The order of a group \$(G, *)\$, denoted \$|G|\$, is the number of elements in the set \$G\$.
Task
The Abelian orders are the integers \$n\$ such that every group of order \$n\$ is Abelian. The sequence of Abelian orders is A051532 in OEIS. Your job is to produce the \$n\$th term of this sequence (1-indexed) given an integer \$n\$. You must support input up to the largest integer such that nothing will overflow.
Input can come from function arguments, command line arguments, STDIN, or whatever is convenient.
Output can be returned from a function, printed to STDOUT, or whatever is convenient. Nothing should be written to STDERR.
Score is number of bytes, shortest wins.
Examples
Here are the first 25 terms of the sequence:
1, 2, 3, 4, 5, 7, 9, 11, 13, 15, 17, 19, 23, 25, 29, 31, 33, 35, 37, 41, 43, 45, 47, 49, 51

Related.

CJam (35 32 bytes)
0q~{{)_mF_z~2f>@::#@m*::%+1&}g}*

Online demo
Dissection
To rephrase some of the information in OEIS, the Abelian orders are the cube-free nilpotent orders; and the nilpotent orders are the numbers n for which no prime power divisor p^k | n is congruent to 1 modulo another prime divisor.
If we pass the cube-free test, the nilpotency test reduces to

No prime factor is equal to 1 modulo another prime factor
If the multiplicity of prime p is k, p^k must not equal 1 modulo another prime factor.

But then the second condition implies the first, so we can reduce it to

If the multiplicity of prime p is k, p^k must not equal 1 modulo another prime factor.

Note that the word "another" is unnecessary, because p^a == 0 (mod p) for a > 0.
0q~{       e# Loop n times starting from a value less than the first Abelian order
  {        e#   Find a number which doesn't satisfy the condition
    )_     e#     Increment and duplicate to test the condition on the copy
    mF     e#     Find prime factors with multiplicity
    _z~    e#     Duplicate and split into the primes and the multiplicities
    2f>    e#     Map the multiplicities to whether or not they're too high
    @::#   e#     Bring factors with multiplicities to top and expand to array of
           e#     maximal prime powers
    @m*::% e#     Cartesian product with the primes and map modulo, so for each
           e#     prime power p^k and prime q we have p^k % q.
    +      e#     Combine the "multiplicity too high" and the (p^k % q) values
    1&     e#     Check whether either contains a 1
  }g
}*

Thank you for the very thorough and intriguing explanation! :)

CJam, 46 45 bytes
0{{)_mf_e`_:e>3a>\{~\,:)f#}%@fff%e_1e=|}g}ri*

Test it here.
I'm using the condition given on the OEIS page:

Let the prime factorization of \$n\$ be \$p_1^{e_1}\cdots p_r^{e_r}\$. Then \$n\$ is in this sequence if \$e_i < 3\$ for all \$i\$ and \$p_i^k \ne 1 \text{ (mod }p_j\text)\$ for all \$i, j\$ and \$1 \le k \le e_i\$ --- T. D. Noe, Mar 25 2007

I'm fairly certain this can be golfed, especially the check of the last condition.

Pyth, 37 bytes
e.f!&tZ|f>hT2JrPZ8}1%M*eMJs.b*LYSNJ)Q

Test suite
Uses the formula from OEIS, cubefree and no prime-power factors that are 1 mod a prime factor, other than 1.

Jelly, 23 bytes
ÆF*/€%þÆfn1ṭÆE<3ƊȦ
1Ç#Ṫ

Try it online!
Takes input via STDIN
How it works
This uses the same condition as the other answers, given on the OEIS page:

Let the prime factorization of \$n\$ be \$p_1^{e_1}\cdots p_r^{e_r}\$. Then \$n\$ is in this sequence if \$e_i < 3\$ for all \$i\$ and \$p_i^k \ne 1 \text{ (mod }p_j\text)\$ for all \$i, j\$ and \$1 \le k \le e_i\$

1Ç#Ṫ - Main link. Takes no arguments
1 #  - Read an integer n from STDIN. Count up k = 1, 2, 3, ... until n such k
       return true under:
 Ç   -   The helper link
   Ṫ - Return the last k

ÆF*/€%þÆfn1ṭÆE<3ƊȦ - Helper link. Takes an integer k on the left
ÆF                 - Yield the prime factorisation of k in [base, exponent] pairs
   /               - Reduce
    €              -   Each
  *                -     By exponentiation
       Æf          - Yield the list of primes whose product is k
     %þ            - Yield a modulo table of these two lists. This takes all pairs
                     from the two lists and reduces each by modulo, yielding a
                     table of all possible modulo pairings. k can only return true
                     iff 1 is not in this table
         n1        - Map 1 -> 0 and everything else to 1
                Ɗ  - Group the previous three links into a monad f(k):
            ÆE     -   Exponents of k's prime factorisation
              <3   -   Less then 3? (vectorises)
                     This yields a binary list of all 1s if k is true else at least 1 0
           ṭ       - Tack. Append the modulo table to the binary list. Call this T
                 Ȧ - Any and all. Does T contain all 1s when flattened and T is non-empty?

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


text:
What song is playing?
Inspired by this xkcd

You work for Shazam and they have a project for you. Some customers are complaining about their app taking up too much space on their phone, so they want you to code a lite version of the app. Unfortunately, your existing code can only understand the word "na", and you have to ship soon. That's okay, we'll do the best with what we've got.
The Challenge
You must write a full program that takes a user input, or takes a command line argument, and print the title and artist of the song. Since we are trying to fix customers complaining about program size, your code must be as short as possible. The input will be a string consisting entirely of na's, with a single space between them. Lowercase/uppercase is arbitrary. This is considered a valid input: Na Na nA na NA This is an invalid input: nah nah NA naNa banana You must determine what song is playing and print it out in exactly this format:
Song: <trackname>
Artist: <artist>

If the input is exactly 8 na's, this matches two separate songs, so you must print both:
Song: Batman Theme
Artist: Neal Hefti

and
Song: Na Na Hey Hey Kiss Him Goodbye
Artist: Steam

If the input is exactly 10 na's, you must print:
Song: Katamari Damacy
Artist: Yuu Miyake

If the input is exactly 11 na's, you must print:
Song: Hey Jude
Artist: The Beatles

If the input is 12 or more na's, you must print
Song: Land Of 1000 Dances
Artist: Wilson Pickett

Lastly, if the input is invalid, there are less than 8 na's, or any of the words are not "na", your program fails to understand the music. So logically, there is only one other song that it could possibly be. You must print:
Song: Africa
Artist: Toto

As usual, standard loopholes apply, and the shortest answer in bytes wins.

great background story!

Isn't Hey Jude 12 nas? I just listened to it and I thought it was (in terms of note lengths) quarter quarter quarter quarter / eighth sixteenth sixteenth quarter-quarter-quarter / eighth sixteenth quarter-quarter-quarter, which is 12 nas.

@Ampora onnnnnnnnne-one-three-one-a-two-threeeeeeeeeee-one-a-two-threeeeeeee-hey-jude definitely 11

Batman is na na / na na / na na / na na x2 batman. I noticed that the second time I saw the comic.

is na na na with a space in the beginning a valid input?

@TanMath for simplicity's sake, we'll say no, you don't have to handle leading spaces.

DJ MC Mayhem? You are built for this challenge, aren't you.

What about 9 nas? Do I print the Africa one?

@nyuszika7h yes.

I'm disturbed to find that Na na hey hey goodbye was by Steam and not originally Bananarama :P

It's 3 years too late to change the challenge, but I must object that the Katamari Damacy theme is titled "Katamari on the Rocks" (or if you're a purist, it's officially "Katamari on the Rocks ~ Main Theme") and thus shouldn't just be listed as just "Katamari Damacy"!

Retina, 242
Try it online!
iG`^na( na)*$
iM`na
m`^8$
>Batman Theme,Neal Hefti$n>Na Na Hey Hey Kiss Him Goodbye,Steam
m`^10$
>Katamari Damacy,Yuu Miyake
m`^11$
>Hey Jude,The Beatles
[0-9].+
>Land Of 1000 Dances,Wilson Pickett
m`^[0-9]
>Africa,Toto
>
Song:
,
$nArtist:

How it works:
IgnoreCase flag + Grep mode flag + Regex ^na( na)*$. If the input is valid, print it as is. If not, print nothing.
iG`^na( na)*$

IgnoreCase flag + Match mode flag + Regex na. Count the "na"s and print the number.
iM`na

If the string is exactly "8", replace by the second line.
m`^8$
>Batman Theme,Neal Hefti$n>Na Na Hey Hey Kiss Him Goodbye,Steam

If the string is exactly "10", replace by the second line.
m`^10$
>Katamari Damacy,Yuu Miyake

If the string is exactly "11", replace by the second line.
m`^11$
>Hey Jude,The Beatles

If the string matches [0-9].+, replace by the second line. This is neither true for single digit numbers, 10 and 11 as they already have been repaced nor any of the above replacement strings.
[0-9].+
>Land Of 1000 Dances,Wilson Pickett

If none of the above matched, the string still starts with a number. Default to Toto, Africa.
m`^[0-9]
>Africa,Toto

Replace the placeholders > and , by Song: and Artist:.
>
Song:
,
$nArtist:

JavaScript (ES6), 276 bytes
alert(`Song: `+([,`Batman Theme,Neal Hefti
Song: Na Na Hey Hey Kiss Him Goodbye,Steam`,,`Katamari Damacy,Yuu Miyake`,`Hey Jude,The Beatles`,`Land Of 1000 Dances,Wilson Pickett`][+prompt(i=0).replace(/na( |$)/gi,_=>++i)&&(i>11?4:i-7)]||`Africa,Toto`).replace(/,/g,`
Artist: `))

Explanation
Input can optionally contain one trailing space.
alert(                 // output the result
  `Song: `+([          // insert the "Song:" label
      ,                // set the first element to undefined in case input is empty

      // Songs
      `Batman Theme,Neal Hefti
Song: Na Na Hey Hey Kiss Him Goodbye,Steam`,
      ,
      `Katamari Damacy,Yuu Miyake`,
      `Hey Jude,The Beatles`,
      `Land Of 1000 Dances,Wilson Pickett`

    ][
      +                // if the input string was made up only of "na"s, the replace would
                       //     return a string containing only digits, making this return a
                       //     number (true), but if not, this would return NaN (false)
        prompt(        // get the input string
          i=0          // i = number of "na"s in input string
        ).replace(     // replace each "na" with a number
          /na( |$)/gi, // find each "na"
          _=>++i       // keep count of the "na"s and replace with a (non-zero) number
        )
      &&(i>11?4:i-7)   // select the song based on the number of "na"s
    ]
      ||`Africa,Toto`  // default to Africa
  ).replace(/,/g,`
Artist: `)             // insert the "Artist:" label
)

Test

var prompt = () => input.value;
var alert = (text) => result.textContent = text;
var solution = () => {

alert(`Song: `+([,`Batman Theme,Neal Hefti
Song: Na Na Hey Hey Kiss Him Goodbye,Steam`,,`Katamari Damacy,Yuu Miyake`,`Hey Jude,The Beatles`,`Land Of 1000 Dances,Wilson Pickett`][+prompt(i=0).replace(/na( |$)/gi,_=>++i)&&(i>11?4:i-7)]||`Africa,Toto`).replace(/,/g,`
Artist: `))

}
<input type="text" id="input" value="na na Na na NA na na nA" />
<button onclick="solution()">Go</button>

This doesn't work for 9 na's, it outputs kamari.

@RikerW Fixed. I forgot a comma...

PowerShell, 278 bytes

Can handle any amount of whitespace
No regex whatsoever!
Implicit typecasting FTW!

@{8='Batman Theme/Neal Hefti','Na Na Hey Hey Kiss Him Goodbye/Steam'
10='Katamari Damacy/Yuu Miyake'
11='Hey Jude/The Beatles'
12='Land Of 1000 Dances/Wilson Pickett'}[[math]::Min($args.Count*!($args|?{$_-ne'na'}),12)]|%{'Song: {0}
Artist: {1}'-f($_+'Africa/Toto'*!$_-split'/')}

Ungolfed
@{8='Batman Theme/Neal Hefti','Na Na Hey Hey Kiss Him Goodbye/Steam' # array
10='Katamari Damacy/Yuu Miyake'
11='Hey Jude/The Beatles'
12='Land Of 1000 Dances/Wilson Pickett'} # Hashtable of songs
[   # Get value by key from hashtable
    # If key is invalid, silently return null value

    [math]::Min( # Clamp max value to 12
        $args.Count* # Multiply count of argumens
                     # true/false will be cast to 1/0
            ! # Negate result of expression
              # Will cast empty array to 'false'
              # and non-empty array to 'true'
            (
                # Return non-empty array if input arguments
                # contain anything other than 'na'
                $args | Where-Object {$_ -ne 'na'}
            ),
        12
    )
] | ForEach-Object { # Send value from hashtable down the pipeline,
                     # This allows to process arrays in hasthable values
    'Song: {0}
    Artist: {1}' -f ( # Format string
        $_+ # Add to current pipeline variable
            'Africa/Toto'*!$_ # If pipeline variable is empty,
                              # then add default song to it
                              # Example: 'Test'*1 = 'Test'
                              #          'Test'*0 = null
        -split '/' # Split string to array for Format operator
    )
}

Usage
PS > .\WhatSong.ps1 na na na na na na na na
Song: Batman Theme
Artist: Neal Hefti
Song: Na Na Hey Hey Kiss Him Goodbye
Artist: Steam

PS > .\WhatSong.ps1 Na na na na na na na na na Na
Song: Katamari Damacy
Artist: Yuu Miyake

PS > .\WhatSong.ps1 Na na na na na na na na na BanaNa
Song: Africa
Artist: Toto

Python 453 440 406 380 bytes
EDIT: Thanks to Cyoce for reducing 13 bytes!
EDIT: Thanks again to Cyoce!
EDIT: Thanks to RainerP. for helping me imrpove the algorithm on certain invalid cases.
This is a rough draft of a Python program. I believe it can be definitely golfed, maybe to 300-400 bytes. But  will work on that soon.
f=0
S='Song:'
A='\nArtist:'
l="Batman Theme,Neal Hefti,Na Na Hey Kiss Him Goodbye,Steam,Katamari Damacy,Yuu Miyake,Hey Jude,Beatles,Land of the 1000 Dances,Wilson Pickett,Africa,Toto".split(',')
s=raw_input().lower()+" "
n=s.count("na ")
n*=n*3==len(s)
if n>11:f=8
if n==10:f=4
if n==11:f=6
if n<8or n==9:f=10
if f:print S+l[f]+A+l[f+1]
else:print S+l[0]+A+l[1]+"\n"+S+l[2]+A+l[3]

Try here!

Instead of that lengthy list, use "Batman Theme,Neal Hefti,Na Na Hey Kiss Him Goodbye,Steam,Katamari Damacy,Yuu Miyake,Hey Jude,Beatles,Land of the 1000 Dances,Wilson Pickett,Africa,Toto".split(',')

Also: instead of if i not in ["n","a"," "]: ... I believe you can use if i not in 'na ': .... Additionally, if f==0: somecode; else: somemorecode can be reduced to if f: somemorecode; else: somecode (0 is Falsy)

Even more (I should have put these all in one, oh well): you have "\nArtist:" three times. try setting a variable, e.g. A="\nArtist:", then using A in place of the string literal. The same can be done with "Song:". Also,  I think that if n<8or n==9:f=10 can be moved to the top of the if statements and changed to if n!=8:f=10

Your program fails to detect invalid input. Output is Batman Theme instead of Africa for na na na nan na na na na.

@RainerP. Thank you... I knew I was missing something... I am now working on an updated algorithm

You can check the input string for validity with  s=raw_input().lower()+" "
n=s.count("na ") (Note the space after the na)
n*=n*3==len(s). n will be 0 for invalid strings.

@RainerP. Thank you, but my approach is to use str.split() to create a list of n "na" 's and count them. If one of the elements is not "na", then nothing is done and n=0 as defined in the beginning. Would that cover all types of invalid input?

You won't need to set set n and i to 0 in the first line and you can drop the loop completely when using my type of check.

@RainerP. so yours is shorter?

Yes. If we add a space to the end and count "na " groups, the number of characters is three times the number of groups for any valid string and greater for any invalid one, so we don't need any additional checks.

Also, your solution fails on certain invalid input as we discussed above.

Let us continue this discussion in chat.

@RainerP. unless you do not want to...

You can change raw_input() to input() and request the input has quotes around it.

sh + coreutils, 290
Albeit longer than my other submission, this one is straightforward and pretty much ungolfed, so i included it anyway.
grep -Ei "^na( na)*$"|wc -w|awk '{s="Song: ";a="\nArtist: ";p=s"Africa"a"Toto"}$1==8{p=s"Batman Theme"a"Neal Hefti\n"s"Na Na Hey Hey Kiss Him Goodbye"a"Steam"}$1>9{p=s"Katamari Damacy"a"Yuu Miyake"}$1>10{p=s"Hey Jude"a"The Beatles"}$1>11{p=s"Land Of 1000 Dances"a"Wilson Pickett"}{print p}'

How it works:
If the input is valid, print it as is. If not, print nothing.
grep -Ei "^na( na)*$"

Count the words.
wc -w

Simple look up table, Song: and Artist: are kept in variables.
awk '
    {s="Song: ";a="\nArtist: ";p=s"Africa"a"Toto"}
    $1==8{p=s"Batman Theme"a"Neal Hefti\n"s"Na Na Hey Hey Kiss Him Goodbye"a"Steam"}
    $1>9{p=s"Katamari Damacy"a"Yuu Miyake"}
    $1>10{p=s"Hey Jude"a"The Beatles"}
    $1>11{p=s"Land Of 1000 Dances"a"Wilson Pickett"}
    {print p}
'

I know it's been a while, but the regex can be shortened to ^(na ?)+$.

Julia, 325 bytes
Probably could be golfed further.
p(s,a)=println("Song: $s\nArtist: $a");ismatch(r"^(na )*na$",ARGS[1])&&(c=length(split(ARGS[1],"na"))-1)==8?(p("Batman Theme","Neal Hefti"),p("Na Na Hey Hey Kiss Him Goodbye","Steam")):c==10?p("Katamari Damacy","Yuu Miyake"):c==11?p("Hey Jude","The Beatles"):c>=12?p("Land Of 1000 Dances","Wilson Pickett"):p("Africa","Toto")

I know it's been a while, but the regex can be shortened to ^(na ?)+$.

Also, the checks can be shortened a bit by using < and > instead of ==: &&(c=length(split(ARGS[1],"na"))-1)<9?(p("Batman Theme","Neal Hefti"),p("Na Na Hey Hey Kiss Him Goodbye","Steam"))c>11?p("Land Of 1000 Dances","Wilson Pickett"):c>10?p("Hey Jude","The Beatles"):c>9?p("Katamari Damacy","Yuu Miyake"):p("Africa","Toto"). Off-topic: I like your Avatar. Finished watching SAO last week. ;)

C (gcc), 403 395 370 365 364 362 bytes
-8 -5 -1 = -14 bytes thanks to ceilingcat
Pretty much as straight-forward as can be.
f(char*s){int*a[]={"Neal Hefti","Steam","Yuu Miyake","The Beatles","Wilson Pickett","Toto","Batman Theme","Na Na Hey Hey Kiss Him Goodbye","Katamari Damacy","Hey Jude","Land Of 1000 Dances","Africa"},i,l=0,j=1;for(;*s;s+=3-!s[2])i=(*s|32)^'n'|(s[1]|32)^97|s[2]>32,l++;for(i=i?5:l^8?l^10?l^11?l>11?4:5:3:2:j++;j--;)printf("Song: %s\nArtist: %s\n",a[6+i--],a[i]);}

Try it online!

@ceilingcat Cheers!

Rust, 501 477 bytes
fn main(){let(mut i,mut n)=(String::new(),0);let(s,a);std::io::stdin().read_line(&mut i);i=i.trim().to_lowercase();let o=i.split(" ");for w in o{if w!="na"{n=0;break}else{n+=1}}match n{8=>{println!("Song: Batman Theme\nArtist: Neal Hefti");s="Na Na Hey Hey Kiss Him Goodbye";a="Steam"}10=>{s="Katamari Damacy";a="Yuu Miyake"}11=>{s="Hey Jude";a="The Beatles"}_=>{if n>=12{s="Land Of 1000 Dances";a="Wilson Pickett"}else{s="Africa";a="Toto"}}}print!("Song: {}\nArtist: {}",s,a)}

Ungolfed
fn main() {
    let (mut input_string, mut na_counter) = (String::new(), 0);
    let (song_name, artist_name);

    std::io::stdin().read_line(&mut input_string);
    input_string = input_string.trim().to_lowercase();
    let output = input_string.split(" ");

    for word in output {
        if word != "na" {
            na_counter = 0;
            break;
        } else {
            na_counter += 1;
        }
    }

    match na_counter {
        8 => {
            println!("Song: Batman Theme\nArtist: Neal Hefti");
            song_name = "Na Na Hey Hey Kiss Him Goodbye";
            artist_name = "Steam";
        }
        10 => {
            song_name = "Katamari Damacy";
            artist_name = "Yuu Miyake";
        }
        11 => {
            song_name = "Hey Jude";
            artist_name = "The Beatles";
        }
        _ => {
            if na_counter >= 12 {
                song_name = "Land Of 1000 Dances";
                artist_name = "Wilson Pickett";
            } else {
                song_name = "Africa";
                artist_name = "Toto";
            }
        }
    }

    print!("Song: {}\nArtist: {}", song_name, artist_name);
}

Edit: removed an unnecessary to_string and type annotations

Perl 5, 312 292 bytes
$_=lc<>;$n="(na ?)";/^(na ){7}na$|(na ){9,}na/ or$_="%Africa&Toto";s/$n{12,}/%Land Of 1000 Dances&Wilson Pickett/;s/$n{11}/%Hey Jude&The Beatles/;s/$n{10}/%Katamari Damacy&Yuu Miyake/;s/$n{8}/%Batman Theme&Neal Hefti\n%Na Na Hey Hey Kiss Him Goodbye&Steam/;s/&/\nArtist: /g;s/%/Song: /g;print

Try it online!
Ungolfed:
$_ = lc <STDIN>;
$_ =~ /^(na ){7}na$|(na ){9,}na/ or $_ = "%Africa&Toto";
$_ =~ s/(na ?){12,}/%Land Of 1000 Dances&Wilson Pickett/;
$_ =~ s/(na ?){11}/%Hey Jude&The Beatles/;
$_ =~ s/(na ?){10}/%Katamari Damacy&Yuu Miyake/;
$_ =~ s/(na ?){8}/%Batman Theme&Neal Hefti\n%Na Na Hey Hey Kiss Him Goodbye&Steam/;
$_ =~ s/&/\nArtist: /g;
$_ =~ s/%/Song: /g;
print $_

I missed some cases, working on a fix now

Perl 5 -pa, 248 bytes
$_=/^(na ?)+$/&&(@F==8?",Batman Theme;Neal Hefti,Na Na Hey Hey Kiss Him Goodbye;Steam":@F==10?"Katamari Damacy;Yuu Miyake":@F==11?",Hey Jude;The Beatles":@F>11?",Land Of 1000 Dances;Wilson Pickett":0)||",Africa;Toto";s/;/
Artist: /gm;s/,/
Song: /gm

Try it online!

UNIX Shell, 394 bytes
uudecode -p<<<'begin-base64 0 -
/Td6WFoAAATm1rRGAgAhARwAAAAQz1jM4AE9AIRdACmbycaLOYv90Azj3HBohRZGa6a5FikeJU+8JbGlB4f9wmi2aQ+mn81aypMRM4nEKPxW439Z2C4WfGeyrREjk427H1GrCRUMHdth+9lVBDiPfCaD8WpStyS0MtJenHKB+tou8rD9INq0yw9IPXuQe7zLM3p14ZDFO8UoJp66scd4bKQAAACSwUb7ERvesgABoAG+AgAARAEAGbHEZ/sCAAAAAARZWg==
===='|unxz|sed -n $#s/,/\\n/gp|grep .||echo $'Song: Land Of 1000 Dances\nArtist: Wilson Pickett'

Test:
; sh $THE_FILE na na na na na na na
Song: Batman Theme
Artist: Neil Hefti

Song: Na Na Hey Kiss Him Goodbye
Artist: Steam

Probably could be optimized, but I just liked this idea TBH :)

Welcome to the site, and nice first answer! Do be aware that a lot of answers use TryItOnline, a free language interpreter, to demonstrate their programs running. I'm not too familiar with UNIX Shell, but I'm sure you could add a link to such a site to allow others to test your code

Java 8, 353 bytes
s->{int n=s.split(" ").length,b=s.matches("(na ?)+")?1:0;s="Africa";return"Song: "+(b>0?n<8?s:n<9?"Batman Theme\nArtist: Neal Hefti\nSong: Na Na Hey Hey Kiss Him Goodbye":n>11?"Land of 1000 Dances":n>10?"Hey Jude":n>9?"Katamari Damacy":"":s)+"\nArtist: "+(b>0?n<8?"Toto":n<9?"Steam":n>11?"Wilson Pickett":n>10?"The Beatles":n>9?"Yuu Miyake":"":"Toto");}

Explanation:
Try it online.
s->{                             // Method with String as both parameter and return-type
  int n=s.split(" ").length,     //  The amount of words when split by spaces
      b=s.matches("(na ?)+")?1:0;//  Whether the input matches the regex "^(na ?)+$"
  s="Africa";                    //  Set the input we no longer need to "Africa"
  return"Song: "                 //  Return "Song: "
    +(b>0?                       //   +If the input matched the regex:
       n<8?                      //     If there are less than 8 "na"'s:
        s                        //      Append "Africa"
       :n<9?                     //     Else-if there are exactly 8 "na"'s:
        "Batman Theme\nArtist: Neal Hefti\nSong: Na Na Hey Hey Kiss Him Goodbye"
                                 //      Append the String above
       :n>11?                    //     Else-if there are 12 or more "na"'s:
        "Land of 1000 Dances"    //      Append "Land of 1000 Dances"
       :n>10?                    //     Else-if there are exactly 11 "na"'s:
        "Hey Jude"               //      Append "Hey Jude"
       :n>9?                     //     Else-if there are exactly 10 "na"'s:
        "Katamari Damacy"        //      Append "Katamari Damacy"
       :                         //     Else (there are exactly 9 "na"'s):
        ""                       //      Append nothing
      :                          //    Else:
       s)                        //     Append "Africa"
    +"\nArtist: "                //   +Append a new-line and "Artist: "
    +(b>0?                       //   +If the input matched the regex:
       n<8?                      //     If there are less than 8 "na"'s:
        "Toto"                   //      Append "Toto"
       :n<9?                     //     Else-if there are exactly 8 "na"'s:
        "Steam"                  //      Append "Steam"
       :n>11?                    //     Else-if there are 12 or more "na"'s:
        "Wilson Pickett"         //      Append "Wilson Pickett"
       :n>10?                    //     Else-if there are exactly 11 "na"'s:
        "The Beatles"            //      Append "The Beatles"
       :n>9?                     //     Else-if there are exactly 10 "na"'s:
        "Yuu Miyake"             //      Append "Yuu Miyake"
       :                         //     Else (there are exactly 9 "na"'s):
        ""                       //      Append nothing
      :                          //    Else:
       "Toto");}                 //     Append "Toto"

05AB1E, 148 bytes
l#„naQW*O5Ý8+@OI5£“‹…0Toto
ßƒ›Ì0Neal Hefti0ÿ¤·¤··—„š‚¿bye0ÁÜ

KatamariÊÖacy0Yuu Miyake
¤· Jude0€€ÊÄ
ˆÑ€‚ 2–›s0¦‹šèett“¶¡0δ¡2₄:¬2ǝ„ŽŸŒá#ÞrèðδÛø„: ý»™

Try it online or verify some more test cases.
Explanation:
l            # Convert the (implicit) input-string to lowercase
 #           # Split it on spaces (if there are any)
  „naQ       # Check for each word if it's equal to "na" (1 if truthy; 0 if falsey)
      W      # Push its minimum, without popping the list itself
       *     # Multiply that to all integers
             # (if any word wasn't "na", the entire list now only contains 0s)
        O    # Sum this list to get the amount of "na"s
5Ý           # Push the list [0,1,2,3,4,5]
  8+         # Add 8 to each: [8,9,10,11,12,13]
    @        # Check for each if the sum is larger than or equal to this value
             # (1 if sum>=n, 0 if sum<n)
     O       # Sum to get the amount of truthy values
I            # Push the input-string
 5£          # Pop and only leave its first 5characters (if it's a valid string,
             # this will be "na na" - with variable casing)
   “‹…0Toto
    ßƒ›Ì0Neal Hefti0ÿ¤·¤··—„š‚¿bye0ÁÜ

    KatamariÊÖacy0Yuu Miyake
    ¤· Jude0€€ÊÄ
    ˆÑ€‚ 2–›s0¦‹šèett“
             # Push dictionary string "africa0 Toto\nbatman theme0Neal Hefti0ÿ hey hey kiss him goodbye0 steam\n\nKatamari damarcy0Yuu Miyake\nhey Jude0 the beatles\nland of 2 dances0 wilson pickett",
             # where the `ÿ` is automatically replaced with the 5-char string
¶¡           # Split this string on newlines
  0δ¡        # And then split each inner string on 0s
             #  [["africa"," Toto"],
             #   ["batman theme","Neal Hefti","na na hey hey kiss him goodbye"," steam"],
             #   [],
             #   ["Katamari damarcy","Yuu Miyake"],
             #   ["hey Jude"," the beatles"],
             #   ["land of 2 dances"," wilson pickett"]]
     2₄:     # Replace the 2 with 1000
        ¬    # Get the first pair (without popping): ["africa"," Toto"]
         2ǝ  # Insert it at (0-based) index 2, replacing the empty list
„ŽŸŒá        # Push dictionary string "song artist"
     #       # Split it on spaces: ["song","artist"]
      Þ      # Cycle this list infinitely: ["song","artist","song","artist",...]
r            # Reverse the values on the stack
 è           # Modulair 0-based index the sum of truthy values into the list of lists of
             # artist(s)/song(s), so 6 will wrap back to the first item
   δ         # Map over each string inside each inner list:
  ð Û        #  And trim all leading spaces
     ø       # Create pairs with the infinitely cycled list, where it will only create
             # as many pairs as the smallest list (so either 2 or 4 in this case)
      „: ý   # Join each inner pair with ": " delimiter
          »  # Then join everything by newlines
           ™ # And finally titlecase each word in the string
             # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why “‹…0Toto ßƒ›Ì0Neal Hefti0ÿ¤·¤··—„š‚¿bye0ÁÜ\n\nKatamariÊÖacy0Yuu Miyake\n¤· Jude0€€ÊÄ\nˆÑ€‚ 2–›s0¦‹šèett“ is "africa0 Toto\nbatman theme0Neal Hefti0ÿ hey hey kiss him goodbye0 steam\n\nKatamari damarcy0Yuu Miyake\nhey Jude0 the beatles\nland of 2 dances0 wilson pickett" and „ŽŸŒá is "song artist".