text:
Play Antichess!
https://en.wikipedia.org/wiki/Losing_chess
This is basically Chess Tournament, but for antichess ;)
Antichess is one of the many chess variants that have been invented. The goal is to lose all your pieces (this may seem a little odd, but it's called antichess for a reason).
The rules
The rules of antichess are very similar to standard chess - but with a few fairly minor differences. The goal as I mentioned above is to lose all your pieces. To make this happen, if your opponent has an opportunity to capture one of your pieces, that is the only move he can make. If you give him multiple chances in one turn, the other player may choose his turn. Another thing that is changed is that the king has no special powers - as in you cannot checkmate your opponent, and you can't force him into check.
The following changes to the standard game will also apply (they help simplify the game):

En passant will be ignored.
Castling isn't possible.
The Fifty-move rule applies automatically (meaning the game ends in a draw).
Pawns will be able to choose what they promote to.
If a player needs longer than 2 seconds to move, he will lose the game.
Returning an invalid move will result in losing the game.
To win, your opponents must capture all your pieces.
White begins the game.
White is placed "at the bottom" of the field (y=0), black is located at the top (y=7).
Accessing other resources than your bot (internet, files, other bots, ...) is prohibited.

Scoring

Winning grants you 3 points, a draw 1 point and losing 0 points.
Each submission will play against each other submission 10 times (5 times as white, 5 as black).

Writing your bot
Controller code is here: https://github.com/JJ-Atkinson/SimpleAntichessKOTH
You can write your bot in either Java or Groovy. To write a bot you must extend the Player class. The player class has one abstract method Move getMove(Board board, Player enemy, Set<Move> validMoves).
Here is a quick rundown on useful methods:
Player:

List<Piece> getPieces(Board board): Return all your pieces that are on the board.
PieceUpgradeType pieceUpgradeType: If/when one of your pawns reaches the end of the board, you will need to define this to the type of piece you want to upgrade to. You have the choice of ROOK, KNIGHT, QUEEN, BISHOP, and KING.

Board:

Field getFieldAtLoc(Location loc): Return the Field at the location. This has a matching getAt method so that if you are using groovy you can write board[loc].
Field getFieldAtLoc(int x, int y): Return the Field at the location. This has a matching getAt method so that if you are using groovy you can write board[x, y].
Board movePiece(Player player, Move move): Make a move on the board so you can see how it would play out. It returns the new board.

If you want to see your opponents pieces, just write enemy.getPieces(board). To add your bot to the lineup add the following line to PlayerFactory:
put(YourBot.class, { new YourBot() } )

Debugging your bot:
I have included a couple of tools to aid in debugging your bots. To see your game played out live you can set the Game#DEBUG flag to true. You will get an output something like this:
Game started. Players: [OnePlayBot(WHITE), SacrificeBot(BLACK)]
...
BLACKs turn.
validMoves: [Move(Piece(BLACK, PAWN, Loc(0, 6)), Loc(0, 5)), ...]
board:
RKBQIBKR
PPPPPPPP
--------
--------
--------
p-------
-ppppppp
rkbqibkr

captureless turns: 1
chosen move: Move(Piece(BLACK, PAWN, Loc(7, 6)), Loc(7, 4))
Game over? false

==============================

WHITEs turn.
validMoves: [Move(Piece(WHITE, ROOK, Loc(0, 0)), Loc(0, 1)), ...]
board:
RKBQIBKR
PPPPPPP-
--------
-------P
--------
p-------
-ppppppp
rkbqibkr

...

(White is upper case, the king is shown with i)
If your console supports utf-8 special chars, you can even show the board with the chess chars by using Board#USE_UTF8_TO_STRING:
♜♞♝♛♚♝—♜
♟—♟♟♟♟♟♟
————————
—♟——————
————————
♙———————
—♙♙♙♙♔♙♙
♖♘♗♕—♗♘♖

(it looks better with a mono spaced font)
To prevent a flood of unwanted output, you should change the Main#main function to something like this:
new Game(new MyBot(), new SacrificeBot()).run()

Put your bot on the left to play as white, put it on the right to play as black.
Building the controller:
The controller is written in groovy, so you must have java and groovy installed. If you don't want to install groovy you can use the gradle build file that comes with the controller (this has not been tested). If you don't want to use groovy or gradle you can use the latest release jar (https://github.com/JJ-Atkinson/SimpleAntichessKOTH/releases). If you do this you need to make your own main method and add your bot manually to the player factory. Example:
PlayerFactory.players.put(YourBot.class, { new YourBot() } )
new Runner().runGames();

(Note that you can still set the debug flags and stuff)
Any and all bug finding is appreciated!
Scores:
SearchBot -> 101
SacrificeBot -> 81
MeasureBot -> 37
RandomBot -> 28
OnePlayBot -> 24

Please note that I'm always willing to have new submissions!

If you like groovy and IntelliJ ... you should take a look at Kotlin

I have seen Kotlin before, but never looked at it thoroughly. It kinda looks like a scala/groovy mashup (but thats OK - groovy and scala are my favorite languages ;)

I've never used scala before ... but it is much easier to call Kotlin code from java than it is to call goovy code from java.

Interesting, I think I made my interface java friendly (all the types are there). I will have to try Kotlin later (I'm reading Learn you a haskell for great good right now)

You can upgrade to a king?!? Surely not...

@wizzwizz4 In antichess, you can.

In Board::isHomeRow(), shouldn't it be loc.y == 0 || loc.y == BOARD_LENGTH - 1?

I think that is the code that I am using...

SearchBot
Slowest bot so far, but still faster than 2 seconds per move and it beats all currently posted bots. It looks at what happens after any of the valid moves and what could happen after any move after those moves and decides what would be the best outcome. Unfortunately it cannot search deeper because it would take more than 2 seconds then.
package com.ppcgse.koth.antichess.player

import com.ppcgse.koth.antichess.controller.Board
import com.ppcgse.koth.antichess.controller.Color
import com.ppcgse.koth.antichess.controller.Location
import com.ppcgse.koth.antichess.controller.Move
import com.ppcgse.koth.antichess.controller.Piece
import com.ppcgse.koth.antichess.controller.PieceType
import com.ppcgse.koth.antichess.controller.PieceUpgradeType
import com.ppcgse.koth.antichess.controller.Player

import groovy.lang.Tuple

/**
 * Created by ProgramFOX on 12/22/15.
 */

 class SearchBot extends Player {
    {pieceUpgradeType = PieceUpgradeType.KING}

    @Override
    Move getMove(Board board, Player opponent, Set<Move> validMoves) {
        return getMoveInternal(board, this, opponent, validMoves, 2)[0]
    }

    Tuple getMoveInternal(Board board, Player whoseTurn, Player opponent, Set<Move> validMoves, Integer depth) {
        def bestScore = null
        def currentlyChosenMove = null
        validMoves.each { m ->
            def opponentPiecesValueBefore = opponent.getPieces(board).sum { getPieceValue(it.getType()) }
            def newBoard = board.movePiece(whoseTurn, m)
            def opponentPiecesValueAfter = opponent.getPieces(newBoard).sum { getPieceValue(it.getType()) }
            if (opponentPiecesValueAfter == null) {
                opponentPiecesValueAfter = 0
            }
            def score = opponentPiecesValueAfter - opponentPiecesValueBefore
            if (whoseTurn.getTeam() == Color.BLACK) {
                score = -score
            }
            if (depth > 1) {
                def validMovesNow = genValidMoves(opponent, whoseTurn, newBoard)
                def goDeeper = true
                if (validMovesNow == null || validMovesNow.size() == 0) {
                    def toAdd = -999
                    if (whoseTurn.getTeam() == Color.BLACK) {
                        toAdd = -toAdd
                    }
                    score += toAdd
                    goDeeper = false
                }
                if (goDeeper) {
                    score += getMoveInternal(newBoard, opponent, whoseTurn, validMovesNow, depth - 1)[1]
                }
            }
            if (bestScore == null) {
                bestScore = score
                currentlyChosenMove = m
            }
            if ((whoseTurn.getTeam() == Color.WHITE && score > bestScore) || (whoseTurn.getTeam() == Color.BLACK && score < bestScore))  {
                bestScore = score
                currentlyChosenMove = m
            }
        }
        return new Tuple(currentlyChosenMove, bestScore)
    }

    Double getPieceValue(PieceType pieceType) {
        switch (pieceType) {
            case PieceType.KING:
                return 1
            case PieceType.PAWN:
                return 1.5
            case PieceType.KNIGHT:
                return 2.5
            case PieceType.BISHOP:
                return 3
            case PieceType.ROOK:
                return 5
            case PieceType.QUEEN:
                return 9
            default:
                return 0
        }
    }

    // Copied from Game.groovy and a bit modified.
    // I actually need this.
    Set<Move> genValidMoves(Player player, Player enemy, Board board) {
        def allMoves = player.getPieces(board).collect { [it, it.getValidDestinationSet(board)] }
        def attackMoves = allMoves
                .collect { pair ->
            def piece = pair[0]
            def dests = pair[1]
            [piece, dests.findAll { board.getFieldAtLoc(it as Location)?.piece?.team == enemy.team }]
        }.findAll { it[1] }

        if (attackMoves.isEmpty())
            return allMoves.collect {
                Piece piece = it[0] as Piece
                return it[1].collect { loc -> new Move(piece, loc as Location) }
            }.flatten() as Set<Move>
        else
            return attackMoves.collect {
                Piece piece = it[0] as Piece
                return it[1].collect { loc -> new Move(piece, loc as Location) }
            }.flatten() as Set<Move>
    }
 }

SacrificeBot
This bot will check all the moves that the other player has and will check to see if any of them intersect (i.e. the piece will be killed). (This does a heck of a lot better than I ever expected ;)
package com.ppcgse.koth.antichess.player

import com.ppcgse.koth.antichess.controller.Board
import com.ppcgse.koth.antichess.controller.Color
import com.ppcgse.koth.antichess.controller.Location
import com.ppcgse.koth.antichess.controller.Move
import com.ppcgse.koth.antichess.controller.Piece
import com.ppcgse.koth.antichess.controller.PieceType
import com.ppcgse.koth.antichess.controller.PieceUpgradeType
import com.ppcgse.koth.antichess.controller.Player

import java.util.concurrent.ThreadLocalRandom

/**
 * Created by Jarrett on 12/19/15.
 */
class SacrificeBot extends Player {

    {pieceUpgradeType = PieceUpgradeType.ROOK}

    @Override
    Move getMove(Board board, Player enemy, Set<Move> validMoves) {
        def enemyPieces = enemy.getPieces(board)
        def pawnMoves = getPawnsMoves(board, enemyPieces)
        def enemyPlayerValidMoves = (enemyPieces
                                        .collect { it.getValidDestinationSet(realBoard) }
                                        .flatten() as List<Location>)
        enemyPlayerValidMoves += pawnMoves

        def sacrificeMove = validMoves
                                .find {enemyPlayerValidMoves.contains(it.destination)}

        if (sacrificeMove)
            return sacrificeMove
        else
            return randomMove(validMoves)
    }

    def randomMove(Set<Move> validMoves) {
        return validMoves[ThreadLocalRandom.current().nextInt(validMoves.size())];
    }

    def getPawnsMoves(Board board, List<Piece> allPieces) {
        def direction = getTeam() == Color.BLACK ? 1 : -1;
        def pawns = allPieces.findAll {it.type == PieceType.PAWN}
        def pawnAttacks = (pawns.collect {
                                    [it.loc.plus(-1, direction), it.loc.plus(1, direction)]
                                }.flatten()
                                ).findAll {
                                    ((Location) it).isValid()
                                }
        return pawnAttacks as List<Location>
    }
}

RandomBot
This is the manditory random bot. It will always upgrade to a rook.
package com.ppcgse.koth.antichess.player

import com.ppcgse.koth.antichess.controller.PieceUpgradeType
import com.ppcgse.koth.antichess.controller.Player
import com.ppcgse.koth.antichess.controller.Move
import com.ppcgse.koth.antichess.controller.ReadOnlyBoard

import java.util.concurrent.ThreadLocalRandom;

public class TestBot extends Player {

    {pieceUpgradeType = PieceUpgradeType.ROOK}

    @Override
    public Move getMove(ReadOnlyBoard board, Player enemy, Set<Move> moves) {
        return moves[ThreadLocalRandom.current().nextInt(moves.size())];
    }

}

OnePlayBot
Dead simple bot with only one play. It will upgrade to a rook.
package com.ppcgse.koth.antichess.player

import com.ppcgse.koth.antichess.controller.Move
import com.ppcgse.koth.antichess.controller.PieceUpgradeType
import com.ppcgse.koth.antichess.controller.Player
import com.ppcgse.koth.antichess.controller.ReadOnlyBoard

public class OnePlayBot extends Player {

    {pieceUpgradeType = PieceUpgradeType.ROOK}

    @Override
    public Move getMove(ReadOnlyBoard board, Player enemy, Set<Move> moves) {
        return new ArrayList<Move>(moves).get(0);
    }

}

MeasureBot
This is the bot that I started with; I was working on expanding it but then I came across the deep-clone bug, and then I thought "well, let's just submit this bot already, it does perform better than RandomBot and OnePlayBot, and I can always submit a new bot later", so here it is:
package com.ppcgse.koth.antichess.player

import com.ppcgse.koth.antichess.controller.Board
import com.ppcgse.koth.antichess.controller.Move
import com.ppcgse.koth.antichess.controller.Piece
import com.ppcgse.koth.antichess.controller.PieceType
import com.ppcgse.koth.antichess.controller.PieceUpgradeType
import com.ppcgse.koth.antichess.controller.Player

import java.util.concurrent.ThreadLocalRandom

/**
 * Created by ProgramFOX on 12/21/15.
 */

 class MeasureBot extends Player {
    {pieceUpgradeType = PieceUpgradeType.KING}

    @Override
    Move getMove(Board board, Player opponent, Set<Move> validMoves) {
        def opponentPieces = opponent.getPieces(board)
        def mustCapture = opponentPieces.find { it.loc == validMoves[0].destination } != null
        def chosen = null
        if (mustCapture) {
            def piecesThatCanBeTaken = opponentPieces.findAll { validMoves.collect { it.getDestination() }.contains(it.loc) }
            def lowestAmount = getPieceValue(piecesThatCanBeTaken.sort { getPieceValue(it.getType()) }[0].getType())
            def piecesWithLowestValue = piecesThatCanBeTaken.findAll { getPieceValue(it.getType()) == lowestAmount }
            def chosenOnes = validMoves.findAll { m -> piecesWithLowestValue.find { it.loc ==  m.destination } != null }
            chosen = chosenOnes.sort { getPieceValue(it.piece.getType()) }.reverse()[0]
        } else {
            chosen = randomMove(validMoves);
        }
        return chosen
    }

    Double getPieceValue(PieceType pieceType) {
        switch (pieceType) {
            case PieceType.KING:
                return 1
            case PieceType.PAWN:
                return 1.5
            case PieceType.KNIGHT:
                return 2.5
            case PieceType.BISHOP:
                return 3
            case PieceType.ROOK:
                return 5
            case PieceType.QUEEN:
                return 9
            default:
                return 0
        }
    }

    def randomMove(Set<Move> validMoves) {
        return validMoves[ThreadLocalRandom.current().nextInt(validMoves.size())];
    }
 }

MeasureBot looks if it needs to capture something: if it does not, it just makes a random move. If it does, it will decide what piece to take: it will choose one with a lower piece value because those can capture fewer of its own pieces. And if there are multiple ways to take a piece with the lowest possible value, it will capture it with the piece with the highest possible value: if it does this, it will bring the capturing piece closer to other pieces (in the beginning of the game, at least) and you'd rather lose a higher-valued piece than a lower-valued one.
This is a list of the piece values I used:

King: 1
Pawn: 1.5
Knight: 2.5
Bishop: 3
Rook: 5
Queen: 9

When a pawn promotes, it will always promote to a king, because it's the lowest-valued piece.


text:
Chaining Programs
Challenge
In this challenge, you will be writing the first program, p1, of an infinite sequence of programs, in which running pn outputs/generates program pn+1. When concatenating the first n >= 2 programs, the sequence should output n.
Example
Let's say the first 4 programs are:
p1 p2 p3 p4

If I were to run p1, it should output:
p2

If I were to run p1p2, it should output:
2

If I were to run p1p2p3p4 it should output:
4

If I were to run p4, it should generate the next program in the sequence:
p5

Scoring
Your score is the byte count of the first 10 programs.

Will the sequences p1p2p3... always be from from p1 to pn?

@Moose Yes, it will always be from p1 to pn.

This is an interesting problem. The program sequence is easy enough; the chaining is harder.

Is accessing files allowed?

@Mauris Yes but the file's content's & name's byte count must be counted in the total byte count for each program it is used in.

@CᴏɴᴏʀO'Bʀɪᴇɴ In some languages it's the other way around

@SuperJedi224 Such as?

This would seem to be the case in, for example, befunge.

Pyth, 12
p1:
l"1

p2: 1
p3: 1
etc..
p1p2p3:
l"111

Output: 3
Explanation:
l        length
 "1      string "1"

On first run, this outputs the length of a single character string, 1. This also happens to be a valid Pyth program, outputting 1 again. Therefore, pn+1 is always 1. When the programs are chained, p1 outputs the length of the chained programs, which will be n.

Lua, 950 900 bytes
s=io.open(arg[0]):read()if#s<95 then print(s)do return end end print(#s/90) do return end;

Ungolfed:
s=io.open(arg[0]):read'*a'
if #s < 96 then
    print(s)
    do return end
end
print(#s/90)
do return end;

Explanation:
The first line grabs the entire source of the program. Then we compare the length of the entire program to 1 + the length of one single program. If the size of the current program is smaller than this value, than the source is printed, which is the next program, p2, and we exit. Each iteration is just a quine. When several of these are put together, the the conditional fails, and we print the length of the concatenated program divided by the length of one program, which is the number of concatenated programs, n.

+1 for using a different method (than mine). This is the type of creative answer I was hoping for.

+1 for Lua, and choosing a cooler, if more lengthy method than the other answers :P

Haha thank you, I was quite proud that i managed to do this with a non-golfing and fairly verbose language :)

Vitsy, 14 bytes
Similar to the Pyth and Jolf answers, I'm mapping strings. The only difference is that I use the line wrapping features to make sure I always get the right length.
p1
'l3-N
p2
1
Replace 1 with any single number.
p3 and so on match this pattern, and you can do this until Integer.MAX_VALUE, the integer restriction of the language.
Explanation:
'l3-N
'     Wrap around the line until finding another '. Since no ' is found before the
      End of the line, it wraps around.
 l    Get the length of the stack.
  3-  Subtract three.
    N Output as number.
Try it online!

Vitsy, 19 bytes
Not dealing with strings here, but using method tricks.
p1
1ml1-\+N
1
p2
1
p3
1
So on, so forth.
Explanation below:
1ml1-\+N
1m       Execute the first index of lines (the bit with the ones)
  l1-    Get the length minus 1.
     \+  Add them all up.
       N Output as number.

1        Push one to the stack.
Try it online!

Seriously, 15 bytes
First program, 6 bytes (contains an unprintable):
5Ql-.

Hex Dump:
35516c2d2e7f

This program prints 1: Try it online
The rest of the programs are all 1, a valid program that prints itself just like the Pyth answer. The original program prints the length of its source code minus 5 and terminates immediately. 1s appended to the end increase the length of the source code by 1 byte each time, but never get executed.

Jolf, 14 bytes
Try it here!
a-lq4
a      print
  lq   the length of the source code
 -  4  minus 4

When executed, this prints 1. Thus, p2 = 1. Executing p2 yields 1. So, for all N > 1, pN = 1.
Observe p1p2: a-1q41. This transpiles to:
alert(sub(length("a-lq41"),4));
1;

Since implicit printing is disabled after the first print, this prints 2, as the length of the source code minus 4 is 2. And on and on and on.

Ruby, 318 bytes
p1:
x=DATA.readlines.size
_="_=%p;puts _%%_"
puts x>0?x+1:_%_
__END__

Each separate program pi outputs this one-line quine: _="_=%p;puts _%%_";puts _%_.
When you add these quines to the end of p1, they end up as lines in the DATA object because they are below the magic __END__.
Here's a test:
$ ruby chain.rb                                    # running p1
_="_=%p;puts _%%_";puts _%_

$ ruby -e '_="_=%p;puts _%%_";puts _%_'            # running p2
_="_=%p;puts _%%_";puts _%_

$ ruby -e '_="_=%p;puts _%%_";puts _%_'            # running p3
_="_=%p;puts _%%_";puts _%_

$ # Concatenating p2 and p3 to p1:
$ ruby -e '_="_=%p;puts _%%_";puts _%_' >> chain.rb
$ ruby -e '_="_=%p;puts _%%_";puts _%_' >> chain.rb

$ ruby chain.rb                                    # running p1p2p3
3

The ten first programs concatenated looks like this (318 bytes):
x=DATA.readlines.size
_="_=%p;puts _%%_"
puts x>0?x+1:_%_
__END__
_="_=%p;puts _%%_";puts _%_
_="_=%p;puts _%%_";puts _%_
_="_=%p;puts _%%_";puts _%_
_="_=%p;puts _%%_";puts _%_
_="_=%p;puts _%%_";puts _%_
_="_=%p;puts _%%_";puts _%_
_="_=%p;puts _%%_";puts _%_
_="_=%p;puts _%%_";puts _%_
_="_=%p;puts _%%_";puts _%_

C#, 2099 + 7 = 2106 bytes

First program (uses compiler flag /main:A):
class A{static void Main(){int a=System.Reflection.Assembly.GetEntryAssembly().GetTypes().Length;var b=@"class A{0}{{static void Main(){{var a=@""{1}"";System.Console.Write(a,{0}+1,a.Replace(""\"""",""\""\""""));}}}}";System.Console.Write(a>1?"{2}":b,0,b.Replace("\"","\"\""),a);}}

Second program:
class A0{static void Main(){var a=@"class A{0}{{static void Main(){{var a=@""{1}"";System.Console.Write(a,{0}+1,a.Replace(""\"""",""\""\""""));}}}}";System.Console.Write(a,0+1,a.Replace("\"","\"\""));}}

Third program:
class A1{static void Main(){var a=@"class A{0}{{static void Main(){{var a=@""{1}"";System.Console.Write(a,{0}+1,a.Replace(""\"""",""\""\""""));}}}}";System.Console.Write(a,1+1,a.Replace("\"","\"\""));}}

You get the idea.

Javascript ES6, score 483 455
Program 1, 77 bytes:
v=1;setTimeout(_=>alert(v>1?v:'a=_=>this.v?v++:alert("a="+a+";a();");a();'));

Program 2 and beyond, 42 bytes each:
a=_=>this.v?v++:alert("a="+a+";a();");a();

PHP, 1470 bytes
Program 1: 219 bytes:
class O{public$n=1;function __destruct(){echo($n=$this->n)>1?$n:'if(!$o->n++)echo str_replace(chr(9),$a=aWYoISRvLT5uKyspZWNobyBzdHJfcmVwbGFjZShjaHIoOSksJGE9CSxiYXNlNjRfZGVjb2RlKCRhKSk7,base64_decode($a));';}}$o=new O();

progam 2 and beyond 139 bytes:
if(!$o->n++)echo str_replace(chr(9),$a=aWYoISRvLT5uKyspZWNobyBzdHJfcmVwbGFjZShjaHIoOSksJGE9CSxiYXNlNjRfZGVjb2RlKCRhKSk7,base64_decode($a));

use like:
php -r "class O{public$n=1;function __destruct(){echo($n=$this->n)>1?$n:'if(!$o->n++)echo str_replace(chr(9),$a=aWYoISRvLT5uKyspZWNobyBzdHJfcmVwbGFjZShjaHIoOSksJGE9CSxiYXNlNjRfZGVjb2RlKCRhKSk7,base64_decode($a));';}}$o=new O();"

Uses a slightly golfed version the php quine technique detailed here: http://10types.co.uk/the-lab/a-minimal-php-quine/

source: Stack Exchange

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

sort: votes


text:
Four is the magic number
I didn't check the sandbox before posting this challenge - it looks like this challenge was proposed by Cᴏɴᴏʀ O'Bʀɪᴇɴ.
Given an integer input, write a program that prints the "four is a magic number" riddle

Four is the magic number
Five is four and four is the magic number
Six is three and three is five and five is four and four is the magic number
Eleven is six and six is three and three is five and five is four and four is the magic number
Five Hundred is eleven and eleven is six and six is three and three is five and five is four and four is the magic number

If you already know the riddle, or are too lazy to solve it anxious to find out what the riddle is, here's an explanation

 The next number is the number of letters in the previous number. So, for example, five has four letters, so the next number is four.

six has three letters, so the next number is 3, and three has five letters, so the next number is 5, and five has four letters, so the next number is 4

 The reason the riddle ends at four is because four has four letters, and four is four and four is four and four is four... (four is the magic number)

Test Cases
0 =>
  Zero is four and four is the magic number
1 =>
  One is three and three is five and five is four and four is the magic number
2 =>
  Two is three and three is five and five is four and four is the magic number
3 =>
  Three is five and five is four and four is the magic number
4 =>
  Four is the magic number
5 =>
  Five is four and four is the magic number
6 =>
  Six is three and three is five and five is four and four is the magic number
7 =>
  Seven is five and five is four and four is the magic number
8 =>
  Eight is five and five is four and four is the magic number
9 =>
  Nine is four and four is the magic number
10 =>
  Ten is three and three is five and five is four and four is the magic number
17 =>
  Seventeen is nine and nine is four and four is the magic number
100 =>
  One Hundred is ten and ten is three and three is five and five is four and four is the magic number
142 =>
  One Hundred Forty Two is eighteen and eighteen is eight and eight is five and five is four and four is the magic number
1,000 =>
  One Thousand is eleven and eleven is six and six is three and three is five and five is four and four is the magic number
1,642 =>
  One Thousand Six Hundred Forty Two is twenty nine and twenty nine is ten and ten is three and three is five and five is four and four is the magic number
70,000 =>
  Seventy Thousand is fifteen and fifteen is seven and seven is five and five is four and four is the magic number
131,072 =>
  One Hundred Thirty One Thousand Seventy Two is thirty seven and thirty seven is eleven and eleven is six and six is three and three is five and five is four and four is the magic number
999,999 =>
  Nine Hundred Ninety Nine Thousand Nine Hundred Ninety Nine is fifty and fifty is five and five is four and four is the magic number

Rules

The input may either be taken from STDIN or as an argument to a function
The input will be a positive number between 0 and 999,999
The input will only contain numbers (it will follow the regex ^[0-9]+$)
The input can either be taken as an integer or a string
When converted to a word string, spaces and hyphens should not be included in the count (100 [One Hundred] is 10 characters, not 11. 1,742 [One thousand Seven hundred Forty-Two] is 31 characters, not 36)
When converted to a string, 100 should be One Hundred, not A Hundred or Hundred, 1000 should be One Thousand, not A Thousand or Thousand.
When converted to a string 142 should be One Hundred Forty Two, not One Hundred and Forty Two
The output is case-insensitive, and should follow the format "N is K and K is M and M is ... and four is the magic number" (unless the input is 4, in which case the output should simply be "four is the magic number")
The output can use numbers instead of letters ("5 is 4 and 4 is the magic number" instead of "five is four and four is the magic number") as long as your program is always consistent
The output can either be the return value of a function, or printed to STDOUT
Standard loopholes apply
This is code-golf, so the shortest program in bytes wins. Good luck!

Bonus
-30 bytes if the program works when the input is between -999,999 and 999,999.
Negative numbers, when converted to words, just have "negative" in front of them. For example -4 is "Negative Four", Negative Four is twelve and twelve is six and six is three and three is five and five is four and four is the magic number
-150 bytes if the program does not use any built-in functions for generating the string representation of the number
Leaderboard
This is a Stack Snippet that generates both a leaderboard and an overview of winners by language.
To ensure your answer shows up, please start your answer with a headline using the following Markdown template
## Language Name, N bytes

Where N is the size, in bytes, of your submission
If you want to include multiple numbers in your header (for example, striking through old scores, or including flags in the byte count), just make sure that the actual score is the last number in your header
## Language Name, <s>K</s> X + 2 = N bytes

var QUESTION_ID=67344;var OVERRIDE_USER=20634;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="
"+e.body.replace(OVERRIDE_REG,"")+"
")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(-?\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
 <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">

Leaderboard

	Author	Language	Size

Winners by Language

Language	User	Score

{{PLACE}}	{{NAME}}	{{LANGUAGE}}	{{SIZE}}	Link

{{LANGUAGE}}	{{NAME}}	{{SIZE}}	Link

Is there a maximum possible input?

In the future, please also check the Sandbox to see if someone else had your idea.

@El'endiaStarman Alright, I added some text at the top of the challenge linking to that post

Your built in function bonus should be more like -150 to -200 bytes.

Relevant sequence from OEIS: A016037

I'm just gonna throw this out there - even the most insanely optimized number to name converters are barely going to cost less than 150 bytes for most languages, as it stands the -150 is more of a trap than a bonus.

@ricdesi That is true - it's more meant to help languages that don't have a built-in way to convert numbers to words

Bash + common utilities (including bsd-games), 123 - 30 = 93 bytes
for((n=$1;n-4;n=m)){
m=`number -l -- $n|sed 's/nus/&&/;s/\W//g'`
s+="$n is $[m=${#m}] and "
}
echo $s 4 is the magic number

Luckily the output from the bsd-games number utility is almost exactly what we need.  Output numbers are all written numerically and not in words as per the 8th bullet point:
$ ./4magic.sh 131072
131072 is 37 and 37 is 11 and 11 is 6 and 6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
$ ./4magic.sh -4
-4 is 12 and 12 is 6 and 6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
$

C, 263 261 bytes - 180 = 81
char*i="jmmonnmoonmpprrqqsrrjjddeeecdd",x;f(n,c){return!n?n:n<0?f(-n,8):n<100?c+i[n<20?n:n%10]-i[20+n/10]:f(n/1000,8)+f(n/100%10,7)+f(n/100%10,0)+c;}main(int c,char**v){for(c=atoi(*++v);c-4;c=x)printf("%d is %d and ",c,x=c?f(c,0)):4;puts("4 is the magic number");}

Inspired by the answer from Cole Cameron.  I thought I might be able to do better without the macro definition.  Although I eventually managed, it did take some squeezing to achieve!
It requires a host character set with consecutive letters (so ASCII is okay, but EBCDIC won't work).  That's for the pair of lookup tables.  I chose j as the zero character, and took advantage of needing two lookups, so I could subtract one from the other rather than having to subtract my zero from both.
Commented version:
char*i=
    "jmmonnmoon"                /* 0 to 9 */
    "mpprrqqsrr"                /* 10 to 19 */
    "jjddeeecdd";               /* tens */
char x;                /* current letter count */

f(n,c){
return
    !n?n                        /* zero - return 0 (ignore c) */
    :n<0?f(-n,8)                /* negative n (only reached if c==0) */
    :n<100?c+i[n<20?n:n%10]-i[20+n/10] /* lookup tables */
    :
      f(n/1000,8)               /* thousand */
    + f(n/100%10,7)             /* hundred */
    + f(n%100,0)                /* rest */
    + c;                        /* carry-in */
}
main(int c, char**v)
{
    for(c=atoi(*++v);c-4;c=x)
        printf("%d is %d and ",c,x=c?f(c,0):4);
    puts("4 is the magic number");
}

There's an obvious extension to support millions, by replacing f(n/1000,8) with f(n/1000000,7)+f(n/1000%1000,8).
Test output
0 is 4 and 4 is the magic number
1 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
2 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
3 is 5 and 5 is 4 and 4 is the magic number
4 is the magic number
5 is 4 and 4 is the magic number
6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
7 is 5 and 5 is 4 and 4 is the magic number
8 is 5 and 5 is 4 and 4 is the magic number
9 is 4 and 4 is the magic number
10 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
17 is 9 and 9 is 4 and 4 is the magic number
100 is 10 and 10 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
142 is 18 and 18 is 8 and 8 is 5 and 5 is 4 and 4 is the magic number
1000 is 11 and 11 is 6 and 6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
1642 is 29 and 29 is 10 and 10 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
70000 is 15 and 15 is 7 and 7 is 5 and 5 is 4 and 4 is the magic number
131072 is 37 and 37 is 11 and 11 is 6 and 6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number
999999 is 50 and 50 is 5 and 5 is 4 and 4 is the magic number

Swift 2, 408 419 - 30 = 389 Bytes
I would be able to get rid of 176 bytes if it Swift wasn't so verbose with regular expressions (removing hyphens and spaces) *glares at Apple*
func c(var s:Int)->String{var r="";while(s != 4){r+="\(s)";let f=NSNumberFormatter();f.numberStyle=NSNumberFormatterStyle.SpellOutStyle;let v=f.stringFromNumber(s)!;s=v.stringByReplacingOccurrencesOfString("[- ]",withString:"",options:NSStringCompareOptions.RegularExpressionSearch,range:Range<String.Index>(start:v.startIndex,end:v.endIndex)).utf8.count+(s<0 ?3:0);r+=" is \(s) and "};return r+"4 is the magic number"}

This can be tested on swiftstub.com, here
I ran a little for loop, and it turns out that 100003 is the number between 0 and 999999 has the longest string result, which has 6 iterations, and is

100003 is 23 and 23 is 11 and 11 is 6 and 6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number

Ungolfed
func a(var s: Int) -> String{
    var r = ""
    while(s != 4){
        r+="\(s)"

        let f = NSNumberFormatter()
        f.numberStyle = NSNumberFormatterStyle.SpellOutStyle
        let v = f.stringFromNumber(s)!
        s = v.stringByReplacingOccurrencesOfString(
            "[- ]",
            withString: "",
            options: NSStringCompareOptions.RegularExpressionSearch,
            range: Range<String.Index>(start: v.startIndex, end: v.endIndex)
        ).utf8.count + (s < 0 ? 3 : 0)

        r+=" is \(s) and "
    }
    return r+"4 is the magic number"
}

NSStringCompareOptions.RegularExpressionSearch And I thought JS's String.fromCharCode was verbose. :P

Python and Ruby: string.replace. Swift: String.stringByReplacingOccurrencesOfString

Mathematica, 156 - 30 = 126 bytes
a=ToString;({a@#," is ",a@#2," and "}&@@@Partition[NestWhileList[#~IntegerName~"Words"~StringCount~LetterCharacter&,#,#!=4&],2,1])<>"4 is the magic number"&

I'm simply surprised that this uses strings and isn't ridiculously long.

Haskell, 285 - 180 = 105 Bytes
In fact, there is no built-in at all for displaying number. I still dissatisfied with the score. Feel free to comment. I will experiment further, though. Still the score is better than Swift's score
c n|n<0=8+c(-n)|n>999=r 1000+8|n>99=7+r 100|n>19=r 10+2-g[30..59]+g[20..29]|n>15=r 10-1|2>1=[0,3,3,5,4,4,3,5,5,4,3,6,6,8,8,7]!!n where{g=fromEnum.elem n;r k=c(mod n k)+c(div n k)}
m 4="4 is the magic number"
m 0="0 is 4 and "++m 4
m n=show n++" is "++show(c n)++" and "++m(c n)

usage
m 7
"7 is 5 and 5 is 4 and 4 is the magic number"
m 999999
"999999 is 50 and 50 is 5 and 5 is 4 and 4 is the magic number"

Explanation.
m is trivial enough, however, the c is not. c is the function to count the number of character the english name of number.
c n |n<0=8+c(-n) -- Add word "negative" in front of it, the length is 8
    |n>999=r 1000+8 -- the english name for number with form xxx,yyy is xxx thousand yyy
    |n>99=7+r 100 -- the english name for number with form xyy is x hundred yy
    |n>19=r 10+2-g[30..59]+g[20..29] -- the english name for number with form xy with x more
                                     -- than 1 is x-ty. However *twoty>twenty,
                                     -- *threety>thirty, *fourty>forty, *fivety>fifty.
    |n>10=r 10-1-g(15:18:[11..13]) -- the english name for number with form 1x is x-teen.
                                     -- However, *oneteen>eleven, *twoteen>twelve,
                                     -- *threeteen>thirteen, *fiveteen>fifteen,
                                     -- *eightteen>eighteen
    |2>1=[0,3,3,5,4,4,3,5,5,4,3]!!n -- for number 0-10, the length is memorized. 0 is 0
                                    -- because it is omitted. Input zero is handled
                                    -- separately. If we defined 0 to be 4, then
                                    -- 20 => twenty zero.
  where g   =fromEnum.elem n      -- Check if n is element of argument array, if true, 1 else 0
        r k=c(mod n k)+c(div n k) -- Obvious.

Oh yea? Well, Swift has... uhm... a higher score... (I'm not very good at comebacks)

C, 268 - 180 = 88 bytes
#define t(x,o)n<x?o:f(n/x)+(n%x?f(n%x):0)
char*i="4335443554366887798866555766";f(n){return t(1000,t(100,n<20?n<0?8+f(-n):i[n]-48:i[n/10+18]-48+(n%10?f(n%10):0))+7)+8;}main(n){for(scanf("%d",&n);n^4;n=f(n))printf("%d is %d and ",n,f(n));puts("4 is the magic number");}

Try it here.
Ungolfed
/* Encode number length in string (shorter representation than array) */
char*i="4335443554366887798866555766";

f(n)
{
    return n < 1000
        ? n < 100
            ? n < 20
                ? n < 0
                    ? 8 + f(-n) /* "Negative x" */
                    : i[n] - 48 /* "x" */
                : i[n/10+18] + (n%10 ? f(n%10) : 0) /* 20-99 */
            : f(n/100) + (n%100 ? f(n%100) : 0) + 7 /* x hundred y */
        : f(n/1000) + (n%1000 ? f(n%1000) : 0) + 8; /* x thousand y */
}

main(n)
{
    /* Keep printing until you get to the magic number */
    for(scanf("%d",&n);n^4;n=f(n))
        printf("%d is %d and ",n,f(n));
    puts("4 is the magic number");
}

Java, 800 - 150 = 650 bytes
class G{static String e="",i="teen",j="ty",k="eigh",y="thir",d="zero",l="one",n="two",m="three",h="four",s="five",c="six",t="seven",b=k+"t",g="nine",D="ten",L="eleven",N="twelve",M=y+i,H=h+i,S="fif"+i,C=c+i,T=t+i,B=k+i,G=g+i,o="twen"+j,p=y+j,q="for"+j,r="fif"+j,u=c+j,v=t+j,w=k+j,x=g+j,A=" ",O=" hundred ",z,E;public static void main(String a[]){z=e;int l=new Integer(a[0]);do{E=a(l,1,e);l=E.replace(A,e).length();z=z+E+" is "+a(l,1,e)+" and ";}while(l!=4);System.out.print(z+h+" is the magic number");}static String a(int P,int _,String Q){String[]f={e,l,n,m,h,s,c,t,b,g,D,L,N,M,H,S,C,T,B,G,e,D,o,p,q,r,u,v,w,x};int R=20,X=10,Y=100,Z=1000;return P==0?(_>0?d:e):(P<R?f[P]+Q:(P<Y?(f[R+(P/X)]+" "+a(P%X,0,e)).trim()+Q:(P<Z?a(P/Y,0,O)+a(P%Y,0,e)+Q:a(P/Z,0," thousand ")+a((P/Y)%X,0,O)+a(P%Y,0,e)+Q)));}}

De-golfed
class G {

   static String e="",i="teen",j="ty",k="eigh",y="thir",d="zero",l="one",n="two",m="three",h="four",s="five",c="six",t="seven",b=k+"t",g="nine",D="ten",L="eleven",N="twelve",M=y+i,H=h+i,S="fif"+i,C=c+i,T=t+i,B=k+i,G=g+i,o="twen"+j,p=y+j,q="for"+j,r="fif"+j,u=c+j,v=t+j,w=k+j,x=g+j,A=" ",O=" hundred ",z,E;

   public static void main(String a[]){
     z = e;
     int l = new Integer(a[0]);
     do {
             E = a(l,1,e);
             l = E.replace(A,e).length();
             z = z+E+" is "+a(l,1,e)+" and ";
     } while(l!=4);
     System.out.println(z+h+" is the magic number");
   }

   static String a(int P,int _,String Q) {
     String[] f = {e,l,n,m,h,s,c,t,b,g,D,L,N,M,H,S,C,T,B,G,e,D,o,p,q,r,u,v,w,x};
     int R=20,X=10,Y=100,Z=1000;
     return P==0?(_>0?d:e):(P<R?f[P]+Q:(P<Y?(f[R+(P/X)]+" "+a(P%X,0,e)).trim()+Q:(P<Z?a(P/Y,0,O)+a(P%Y,0,e)+Q:a(P/Z,0," thousand ")+ a((P/Y)%X,0,O)+a(P%Y,0,e)+Q)));
   }
}

I know it's been more than a year, but you can remove some parenthesis in that ternary assignment as well as change ==0 to <1. So: return P<1?_>0?d:e:P<R?f[P]+Q:P<Y?(f[R+(P/X)]+" "+a(P%X,0,e)).trim()+Q:P<Z?a(P/Y,0,O)+a(P%Y,0,e)+Q:a(P/Z,0," thousand ")+a((P/Y)%X,0,O)+a(P%Y,0,e)+Q; (- 10 bytes)

QC, 265 - 30 - 150 = 85 bytes
(✵1:oaT%=ta100%=ha100/⌋T%=X[0 3 3 5 4 4 3 5 5 4 3 6 6 8 8 7 7 9 8 8]=Y[6 6 5 5 5 7 6 6]=a0≟4a20<Xt☌YtT/⌋2-☌Xo☌+▲▲hXh☌7+0▲+)(❆1:na0<8*=ba‖1000/⌋=ca1000%=nbb✵8+0▲a✵++){I4≠:EEI" is "++=II❆=EEI" and "++=E!}E"4 is the magic number"+

Test suite
Ungolfed:
(✵1:
oaT%=                                        # ones
ta100%=                                      # tens
ha100/⌋T%=                                   # hundreds
X[0 3 3 5 4 4 3 5 5 4 3 6 6 8 8 7 7 9 8 8]=  # length of "zero", "one", "two", ..., "nineteen"
Y[6 6 5 5 5 7 6 6]=                          # length of "twenty", ..., "ninety"
a0≟
  4
  a20<
    Xt☌
    YtT/⌋2-☌ Xo☌ +
  ▲
▲
hXh☌7+0▲+)

(❆1:
na0<8*=                 # if negative, add 8
ba‖1000/⌋=              # split aaaaaa into bbbccc
ca1000%=
n bb✵8+0▲ a✵ ++)

{I4≠:EEI" is "++=II❆=EEI" and "++=E!}E"4 is the magic number"+

If you're not using a built-in function for getting the length of the number, so you can actually subtract another 150 from your score

JavaScript, 382 - 150 - 30 = 202 bytes
var o=[0,3,3,5,4,4,3,5,5,4],f=s=>(s[1]==1?[3,6,6,8,8,7,7,9,8,8][s[0]]:o[s[0]]+(s.length>1?[0,3,6,6,5,5,5,7,6,6][s[1]]:0))+(s.length==3?(7+o[s[2]]-(o[s[2]]==0?7:0)):0),l=n=>{var s=(""+n).split("").reverse();return f(s.slice(0,3))+(s.length>3?(f(s.slice(3,6))+8):0)};(n=>{var s="";while(n!=4){s+=n+" is ";n=n>=0?l(n):(l(-n)+8);s+=n+" and ";}console.log(s+"4 is the magic number");})()

The input is given as the parameter to the Immediately-Invoked Function Expression.
Test input:
999999 ->
    999999 is 50 and 50 is 5 and 5 is 4 and 4 is the magic number
17 ->
    17  is 9 and 9 is 4 and 4 is the magic number
-404 ->
    -404 is 23 and 23 is 11 and 11 is 6 and 6 is 3 and 3 is 5 and 5 is 4 and 4 is the magic number

De-golfed:
// array of the lengths of digits in ones place:
// one is 3, two is 3, three is 5, etc... zero is a special case
// and is assigned zero length because zero is never written out in a number name
var o=[0,3,3,5,4,4,3,5,5,4],

// function that computes the length of a substring of the input
// because the input is 6 digits, it can be broken into two 3 digit subsections
// each of which can have it's length calculated separately
f=s=>
  (
  s[1]==1? // check for if the tens digit is a one
    // when the tens is a one, pull the string length from an array that represents
    // ten, eleven, twelve, thirteen, etc...
    [3,6,6,8,8,7,7,9,8,8][s[0]]
  :
    // when the tens digit is not a one, add the ones digit normally and...
    o[s[0]]
    +
    // add the tens digit length from the array that represents
    // zero, ten, twenty, thirty, forty, fifty, sixty, seventy, eighty, ninety
    (s.length>1?[0,3,6,6,5,5,5,7,6,6][s[1]]:0)
  )
  +
  (
  s.length==3? // check if the length is 3 and weren't not accidentally trying to do something wierd with a minus sign
    // if so, then we have to add a hundred (7 characters) to the length and the
    // length of the ones digit that is in the hundreds place like
    // 'one' hundred or 'two' hundred
    (7+o[s[2]]-
      (
        // also, if the hundreds place was a zero, subtract out those 7 characters
        // that were added because 'hundred' isn't added if there's a zero in its
        // place
        o[s[2]]==0?
          7
        :
          0
      )
    )
  :
    // if the length wasn't 3, then don't add anything for the hundred
    0
  ),

// function that computes the length of the whole six digit number
l=n=>{
  // coerce the number into a string and then reverse the string so that the
  // ones digit is the zeroth element instead of last element
  var s=(""+n).split("").reverse();
  return
    // calculate the character length of the first 3 characters
    // like in the number 999888, this does the '888'
    f(s.slice(0,3))
    +
    // then if there actually are any characters after the first 3
    (s.length>3?
        // parse the character length of the second 3 characters
        (f(s.slice(3,6))+8)
      :
        0
    )
};
// lastly is the Immediately-Invoked Function Expression
(n=>{
  var s="";
  // as long as we haven't reached four, just keep going through the loop
  while(n!=4){
    s+=n+" is ";
    n=n>=0?l(n):(l(-n)+8) // this handles negatives by only passing positive values to l and then just adding 8 onto the length for negatives
    s+=n+" and ";
  }
  // finally just say that '4 is the magic number'
  console.log(s+"4 is the magic number");
})(999999)

Moo, 182 176/192 188 bytes - 30 = 146/158
188 byte version:
u=$string_utils;s="";i=args[1];while(i-4)j=u:english_number(i);s=s+j+(s?" and "+j|"")+" is ";i=length(u:strip_chars(j,"- "}));endwhile;return s+(s?"four and "|"")+"four is the magic number"

176 byte implementation-dependent version:
s="";i=args[1];while(i-4)j=#20:english_number(i);s=s+j+(s?" and "+j|"")+" is ";i=length(#20:strip_chars(j," -"));endwhile;return s+(s?"four and "|"")+"four is the magic number"

Both are functions.

Python 641-150 = 501 bytes
At least it isn't longer than Java! It is based on this except using strings.
EDIT: I forgot about 0 and that I need to say "5 is 4", not skip to "4 is the magic number" - that added a bit to the score.
w={0:"zero",1:"one",2:"two",3:"three",4:"four",5:"five",6:"six",7:"seven",8:"eight",9:"nine",10:"ten",11:"eleven",12:"twelve",13:"thirteen",14:"fourteen",15:"fifteen",16:"sixteen",17:"seventeen",18:"eighteen",19:"nineteen",20:"twenty",30:"thirty",40:"forty",50:"fifty",60:"sixty",70:"seventy",80:"eighty",90:"ninety"}
s=""
def i(n):
 global s
 e=""
 o=n%10
 t=n%100
 h=n/100%10
 th=n/1000
 if th:
  e+=i(th)
  e+='thousand'
 if h:
  e+=w[h]
  e+='hundred'
 if t:
  if t<20 or o==0:
   e+=w[t]
  else:
   e+=w[t-o]
   e+=w[o]
 if len(e)==4:s+="4 is the magic number";print s
 else: s+="%d is %d and "%(n,len(e));i(len(e))
In=input()
i(In)

Try it here!

You don't have to display the name, right?

This is incorrect. i(5) prints 4 is the magic number, instead of 5 is 4 and 4 is the magic number.

PHP, 168 - 30 = 138 bytes
function m($i){$e=strlen(preg_replace('/[^a-z-]/','',(new NumberFormatter("en",5))->format($i)));echo($i==$e?"":"$i is $e and "),($e==4?"4 is the magic number":m($e));}

all_licenses: 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/


text:
Bacterial expansion
Colonies of bacteria labelled 1 through 9 live on a segment of equally-spaced cells, with empty cells indicated by 0
0 0 2 0 0 0 1 2 0 0 3 3 0 0

Every second, each colony spreads to adjacent empty cells. If two colonies reach an empty cell at the same time, the larger-labeled colony takes it.
t=0:  0 0 2 0 0 0 1 2 0 0 3 3 0 0
t=1:  0 2 2 2 0 1 1 2 2 3 3 3 3 0
t=2:  2 2 2 2 2 1 1 2 2 3 3 3 3 3

The colonies cannot spread beyond the boundaries. A colony is never displaced by another colony, so once all empty cells are filled, nothing further changes.
Given the initial state, output or print the final state. Use any reasonable list or string format. You should not output any intermediate states. The input will contain at least one bacterial colony.
Related: Cover up zeroes in a list. (The colonies only spread to the right.)
Test cases: Output below input.
0 0 2 0 0 0 1 2 0 0 3 3 0 0
2 2 2 2 2 1 1 2 2 3 3 3 3 3

7 0 3 0 0 0 0 0 8 0 9 1
7 7 3 3 3 8 8 8 8 9 9 1

5 0 3 0 0 0
5 5 3 3 3 3

7 7 1
7 7 1

1 0 1
1 1 1

    var QUESTION_ID=64812,OVERRIDE_USER=20260;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/67346/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="
"+e.body.replace(OVERRIDE_REG,"")+"
")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
    body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
     <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">

Leaderboard

	Author	Language	Size

Winners by Language

Language	User	Score

{{PLACE}}	{{NAME}}	{{LANGUAGE}}	{{SIZE}}	Link

{{LANGUAGE}}	{{NAME}}	{{SIZE}}	Link

JavaScript (ES6), 66 62 bytes
a=>a.map(_=>a=a.map((c,i)=>c||Math.max(a[i-1]|0,a[i+1]|0)))&&a

Explanation
a=>                 // a = input as array of numbers
  a.map(_=>         // loop for the length of a, this ensures the end is always reached
    a=a.map((c,i)=> // update a after to the result of t, for each cell c of index i
      c||           // keep the cell if it is not 0
        Math.max(   // else set the cell to the max value of:
          a[i-1]|0, //     the previous cell (or 0 if i - 1 less than 0),
          a[i+1]|0  //     or the next cell (or 0 if i + 1 greater than the length of a)
        )
    )
  )
  &&a               // return a

Test

var solution = a=>a.map(_=>a=a.map((c,i)=>c||Math.max(a[i-1]|0,a[i+1]|0)))&&a
Cell numbers separated by spaces = <input type="text" id="input" value="7 0 3 0 0 0 0 0 8 0 9 1" />
<button onclick="result.textContent=solution(input.value.split(' ').map(n=>+n)).join(' ')">Go</button>

Pyth, 18 bytes
um|@d1eSd.:++0G03Q

Test suite
Takes input as a list of integers.
Essentially, this uses a apply until convergence loop, u. It applies the update by forming all lists of each cell and the two cells on either side, then updating each zeroed cell to the max of its neighbors.
um|@d1eSd.:++0G03Q
                      Implicit: Q = eval(input())
u                Q    Apply the following until convergence, starting with G = Q.
           ++0G0      Pad G with zeros on either side.
         .:     3     Form all 3 element substrings.
                      Now, for each element of G, we have a list of the form
                      [previous, current, next]
 m                    Map over this list
  |@d1                The current element, if it's nonzero
      eSd             Else the max of the list.

Mathematica, 77 bytes
Not very competitive compared with alephalpha's //. solution, but I figured a  cellular-automata challenge should have a CellularAutomaton answer:
CellularAutomaton[{If[#2<1,Max@##,#2]&@@#&,{},1},{#,0},{{{l=Length@#}},l-1}]&

The function takes a ton of parameters... let's give them some names:
CellularAutomaton[{f,n,r},{i,b},{{{t}},d}]

Here is what they do:

r is the range of the rule, that is, it determines how many neighbours are considered for the update. We want one neighbour on each side, so we use 1.
n is normally the number or list of colours (different cell types), but if we specify the rule as a custom function instead of a rule number, this should be {}.
f is a function determining the update rule. It takes a list of 3 cells (if r = 1) and returns the new colour for the middle cell.
i is the initial condition. That's the input.
b is the background. If this isn't given, CellularAutomaton uses periodic boundaries, which we don't want. Instead using 0 imposes a dead boundary condition.
t is the number of times to simulate. We don't need more steps than the input is wide, because after that the bacteria will have converged, so t = Length@#. Normally, CellularAutomaton returns all intermediate steps. We can avoid that by wrapping t in two lists.
d determines which cells are presented in the output. By default, we would get all the cells that could potentially be affected by the rule (which is t*r additional cells on either end of the input). We give it l-1, because this is one of the few situations in Mathematica where a zero-based index is used.

Haskell, 86 83 81 79 73 71 bytes
(0#r)l=max r l
(o#_)_=o
p!_=zipWith3(#)p(0:p)$tail p++[0]
id>>=foldl(!)

Usage example: id>>=foldl(!) $ [7,0,3,0,0,0,0,0,8,0,9,1] -> [7,7,3,3,3,8,8,8,8,9,9,1].
Nothing much to explain: if a cell is 0, take the maximum of the neighbor elements. Repeat length-of-the-input times. For this I iterate over x via foldl but ignore the second argument in p.
Edit: @Mauris found 6 bytes to save and @xnor another two. Thanks!

You can replace h p with p!_ then replace (const.h) with (!) to save 6 bytes.

@Mauris: Clever. Thanks a lot!

@nimi I think the last line anonymizes to id>>=foldl(!).

@xnor: yes it does! Well spotted!

CJam, 27 24 bytes
{_,{0\0++3ew{~@e>e|}%}*}

Test it here.
This pushes an unnamed block which transforms a list on the stack into a new list.
Explanation
_,       e# Duplicate the input and get its length N.
{        e# Run this block N times (convergence won't take that long)...
  0\0++  e#   Wrap the list in two zeroes.
  3ew    e#   Get all sublists of length 3.
  {      e#   Map this block onto each sublist...
    ~    e#     Dump all three elements on the stack.
    @    e#     Pull up the left neighbour.
    e>   e#     Maximum of both neighbours.
    e|   e#     Logical OR between centre cell and maximum of neighbours.
  }%
}*

Sidestepping convergence is a nice trick

... which I shamelessly borrowed :-)

J, 24 23 bytes
(+=&0*(0,~}.)>.0,}:)^:_

Usage:
   ((+=&0*(0,~}.)>.0,}:)^:_) 0 1 5 0 0 0 6
1 1 5 5 6 6 6

Method is similar to Mauris' solution.
(                  )^:_ repeat until change
               0,}:     concat 0 and tailless input
      (0,~}.)           concat headless input and 0
             >.         elementwise maximum of the former two lists
  =&0*                  multiply by input_is_0 (zeroing out the list at nonzero input positions)
 +                       add to input

Try it online here.
1 byte saved thanks to Zgarb.

Mathematica, 77 74 66 62 bytes
Saved 12 bytes thanks to Martin Büttner.
#//.i_:>BlockMap[If[#2<1,Max@##,#2]&@@#&,Join[{0},i,{0}],3,1]&

Python 3.5, 83 bytes
This function takes a Python list of integers. Not sure there's much left to golf, but I'd love to get it competitive with another language at least!
def b(s):
 for _ in s:s=[s[n]or max((0,*s)[n:n+3])for n in range(len(s))]
 return s

From Python 3.5, PEP 448 lets us unpack s into 0,*s. Earlier releases require one byte extra, like so:
def b(s):
 for _ in s:s=[s[n]or max(([0]+s)[n:n+3])for n in range(len(s))]
 return s

Credit to user81655's solution and explanation for helping me realise that I don't need to test whether the list has stopped changing; I just need to iterate enough times to be sure all zeroes must have been covered. (The maximum number of iterations needed is one less than the length of the list; this does one iteration more than that, because that takes less code.)

@ChrisH: It doesn't work on Python 3.5, and I don't think it would work on earlier versions either: doesn't that move the return to inside the for _ in s loop?

comment deleted -- I happened to only try the test cases that resolve first time.

J, 33 bytes
3 :'y+(y=0)*>./(_1,:1)|.!.0 y'^:_

A bit longer than I would've liked.
3 :'                         '^:_   Repeat a "lambda" until a fixed point:
                            y         The input to this lambda.
               (_1,:1)|.!.0           Shift left and right, fill with 0.
            >./                       Maximum of both shifts.
      (y=0)*                          Don't grow into filled cells.
    y+                                Add growth to input.

That's so different from what I have, I think you should post it as an answer :)

Matlab, 90 bytes
How about some convolutions?
x=input('');for n=x;x=x+max(conv(x,[0 0 1],'same'),conv(x,[1 0 0],'same')).*~x;end;disp(x)

Example
>> x=input('');for n=x;x=x+max(conv(x,[0 0 1],'same'),conv(x,[1 0 0],'same')).*~x;end;disp(x)
[7 0 3 0 0 0 0 0 8 0 9 1]
     7     7     3     3     3     8     8     8     8     9     9     1

Haskell, 66 65 bytes
f x=[maximum[[-j*j,a]|(j,a)<-zip[-i..]x,a>0]!!1|(i,_)<-zip[0..]x]

This defines a function called f.
Explanation
Instead of iterating the cellular automaton, I compute the final values directly. The definition is a single list comprehension. The value i ranges from 0 to length x - 1, since we zip x with the natural numbers. For each index i, we produce the list of 2-element lists
[-(-i)^2, x0], [-(-i+1)^2, x1], [-(-i+2)^2, x2], ..., [-(-i+n)^2, xn]

From this list, we compute the maximal element whose second coordinate is nonzero and take that second element with !!1. This gives the closest nonzero value to index i, breaking ties by taking the larger value.

Congrats on winning the bounty!

Lua, 133 bytes
Two loops, nested ternaries... If I want to golf it further, I will have to find an other way to do it, but I don't see one.
function f(a)for i=1,#a do b={}for j=1,#a do c,d=a[j+1]or 0,a[j-1]b[j]=0c and d or c end a=b end return a end

Explanations
function f(a)
  for i=1,#a                       -- this loop allow us to be sure the cycle is complete
  do
    b={}                           -- set a new pointer for b
    for j=1,#a                     -- loop used to iterate over all elements in a
    do
      c,d=a[j+1]or 0,a[j-1]        -- gains some bytes by attributing these expressions
                                   -- to a variable
      b[j]=0c and d or c
    end
    a=b                            -- we are one cycle further, new value for a
  end                              -- which is our reference array
  return a
end

The part
b[j]=0c and d or c

will be expanded to
b[j]=0(a[j+1] or 0) and a[j-1] or(a[j+1]or 0)

which can be translated in nested if as
if 0<a[j]
then
    value=a[j]          -- if the cell isn't at 0, it keeps its value
elseif (a[j-1] or 0)<(a[j+1] or 0)
--[[ x or y as the following truth table :
x | y ||x or y
------||-------
0 | 0 || false
0 | 1 ||   y
1 | 0 ||   x
1 | 1 ||   x
    -- It means that when j=1 (1-based) and we try to index a[j-1]
    -- instead of failing, we will fall in the case false or true
    -- and use the value 0
    -- the same trick is used for when we try to use an index > a:len
]]--
then
    value=a[j-1]        -- the left cell propagate to the cell j
else
    value=a[j+1] or 0   -- if j=a:len, we put 0 instead of a[j+1]
                        -- this case can only be reached when we are on the right most cell
                        -- and a[j-1]==0
end

APL (Dyalog), 18 bytes
Anonymous tacit prefix function.
(⊢+~∘××3⌈/0,,∘0)⍣≡

Try it online!
(…)⍣≡ apply the following tacit function until the result is identical to the argument:
 ⊢ the argument
 + plus
  ~ not
  ∘ the
  × signum
 × times
 3⌈/ the maxima over each group of three of
 0, zero followed by
  , the argument followed by
  ∘ a
  0 zero

Husk, 15 bytes
ω(m?!2▲!2X3`:0Θ

Try it online!
Explanation
ω(m?!2▲!2X3`:0Θ
ω(              iterate until fixed point:
           `:0Θ prepend and append 0
         X3     take overlapping segments of 3 elements
  m             map to:
   ?   !2        if second element is truthy:
    !2            leave as is
      ▲           else take maximum

Pyth, 17 bytes
meeSe#.e,_akdbQUQ

Takes a Python-style list from stdin, outputs to stdout.
Explanation
This is basically a translation of my Haskell answer. I haven't really used Pyth before, so hints are welcome.
                   Implicit: Q is input list
m              UQ  Map over input index d:
      .e      Q     Map over input index k and element b:
        ,_akdb       The pair [-abs(k-d), b]
    e#              Remove those where b==0
 eeS                Take the second element of the maximal pair

Java 8, 155 142 bytes
a->{for(int b[],i,l=a.length,p,n,f=l;f>0;)for(b=a.clone(),i=0,f=l;i<l;f-=a[i-1]>0?1:0)if(a[i++]<1)a[i-1]=(p=i>1?b[i-2]:0)>(n=i<l?b[i]:0)?p:n;}

Modifies the input int[] instead of returning a new one to save bytes.
Explanation:
Try it here.
a->{                   // Method with integer-array parameter and no return-type
  for(int b[],         //  Copy array
          i,           //  Index integer
          l=a.length,  //  Length of the array
          p,n,         //  Temp integers (for previous and next)
          f=1;         //  Flag integer, starting at 1
      f>0;)            //  Loop (1) as long as the flag is not 0 (array contains zeroes)
    for(b=a.clone(),   //   Create a copy of the current state of the array
        i=0,           //   Reset the index to 0
        f=l;           //   Reset the flag to the length of the array `l`
        i<l;           //   Inner loop (2) over the array
        f-=a[i-1]>0?   //     After every iteration, if the current item is not a zero:
            1          //      Decrease flag `f` by 1
           :           //     Else:
            0)         //      Leave flag `f` the same
      if(a[i++]<1)     //    If the current item is a 0:
        a[i-1]=        //     Change the current item to:
         (p            //      If `p` (which is:
           =i>1?       //        If the current index is not 0:
             b[i-2]    //         `p` is the previous item
            :          //        Else:
             0)        //         `p` is 0)
         >(n           //      Is larger than `n` (which is:
            =i<l?      //        If the current index is not `l-1`:
              b[i]     //         `n` is the next item
             :         //        Else:
              0)?      //         `n` is 0):
          p            //       Set the current item to `p`
         :             //      Else:
          n;           //       Set the current item to `n`
                       //   End of inner loop (2) (implicit / single-line body)
                       //  End of loop (1) (implicit / single-line body)
}                      // End of method

Ruby, 81 bytes
->(a){a.map{|o|a=a.map.with_index{|x,i|x!=0 ? x : a[[0,i-1].max..i+1].max}}[-1]}

I think the inner map could be further golfed.

Just realized, my answer is kinda identical to @user81655 's answer.

I think you can remove the spaces in the ternary, i.e. around ? and :.

PHP - 301 291 289 288 264 Characters
Didn't peak at other answers before attempting this. Don't blame the language, blame me. Very enjoyable and challenging non the less. All code golf advice heavily appreciated.
$a=explode(' ',$s);$f=1;while($s){$o=1;foreach($a as&$b){
if($b==0){$u=current($a);prev($a);$d=prev($a);if(!$o&&current($a)==0){end($a);$d=prev($a);}if(!$f){$f=1;continue;}if($u>$d)$b=$u;if($u<$d){$b=$d;$f=0;}}
$o=0;}if(!in_array(0,$a))break;}$r=join(' ',$a);echo$r;

Explained
// Input
$s = '0 0 2 0 0 0 1 2 0 0 3 3 0 0';

// Create array
$a = explode(' ', $s);
// Set skip flag
$f = 1;
while ($s)
{
    // Set first flag
    $o = 1;
    // Foreach
    foreach ($a as &$b)
    {
        // Logic only for non zero numbers
        if ($b == 0)
        {
            // Get above and below value
            $u = current($a);
            prev($a);
            $d = prev($a);

            // Fix for last element
            if (! $o && current($a) == 0)
            {
                end($a);
                $d = prev($a);
            }

            // Skip flag to prevent upwards overrun
            if (! $f)
            {
                $f = 1;
                continue;
            }

            // Change zero value logic
            if ($u > $d)
                $b = $u;
            if ($u < $d)
            {
                $b = $d;
                $f = 0;
            }
        }

        // Turn off zero flag
        $o = 0;
    }

    // if array contains 0, start over, else end loop
    if (! in_array(0, $a))
        break;
}
// Return result
$r = join(' ', $a);
echo $r;(' ', $a);
echo $r;

Seriously? Golfing isn't just removing the whitespaces in your code. Besides the algorithm, here are some tips: use 1 rather than true, split rather than explode, for rather than while, join rather than implode, remove useless curly brackets, …

I kept explode because split is being depreciated. Also, I don't know how to write a while loop using for, so I kept it for now, unless someone here can share their knowledge or share a link. Thank you all.

MATL, 38 bytes
Direct translation of my Matlab answer. Uses current version of language/compiler.
it:"tttFFTo2X5I$X+wTFFo2X5I$X+vX>w~*+]

Example
>> matl it:"tttFFTo2X5I$X+wTFFo2X5I$X+vX>w~*+]
> [7 0 3 0 0 0 0 0 8 0 9 1]
7 7 3 3 3 8 8 8 8 9 9 1

EDIT: Try it online! with X+ replaced by Y+ and v by &v, owing to changes done in the language.

Python, 71 bytes
g=lambda l:l*all(l)or g([l[1]or max(l)for l in zip([0]+l,l,l[1:]+[0])])

The zip creates all length-3 sublists of an element and its neighbors, treating beyond the endpoints as 0. The central element l[1] a sublist l, if zero, is replaced by the max of its neighbors with l[1]or max(l). The l*all(l) returns the list l when it has no 0's.

Ruby, 74 bytes
->a{(r=0...a.size).map{|n|a[r.min_by{|i|[(a[i]<1)?1:0,(i-n).abs,-a[i]]}]}}

works by finding the closest non-zero number.