Scala - 247 196
(+ 4 separators)
Being a beginner at Scala, I found the challenge interesting for a functional approach, but I fear I haven't took a concise approach. I guess a seasoned Scala coder will make a one liner... Particularly if I missed a useful collection method!
Anyway, here is the golfed version, even if it is out of competition:
readLine;val n=(readLine+" z").split(' ')
def g(v:String)={var a=1
(n:String)=>{if(n==v){a+=1;Nil}else List(a,v)}}
var p=g(n.head)
print(n.tail.flatMap{n=>val r=p(n);if(r!=Nil)p=g(n);r}.mkString(" "))
I feel the newlines should be counted (as spaces) as here they are mandatory separators. But well, the Python scripts above doesn't count them (while they are mandatory too), so I hadn't either...
The uncompressed version, with comments for my own benefit:
// Read the stdin, skipping the first line, returning the second one
// cat input.txt | scala RLE.scala
readLine // Thanks Daniel!
val line = readLine
// Add an arbitrary symbol that is dropped in the process... (trigger last sequence processing)
val numbers = (line + " z").split(' ')
println(numbers mkString " ")
/** Returns a closure to process the given value in the sequence to come */
def getSeq(value: String) =
{
var acc = 1
// Make a closure over value and acc
(n: String) =>
{
if (n == value)
{
acc += 1
Nil
}
else // Different value, return the cumulation so far
{
List(acc, value)
}
}
}
var process = getSeq(numbers.head) // Initial closure
/** Processes the numbers in the sequence. */
def accumulate(n: String) =
{
val p = process(n)
if (p != Nil) // We got a result
{
process = getSeq(n) // We need a fresh function over the new sequence that starts
}
p
}
println(numbers.tail.flatMap(accumulate).mkString(" "))
Feels clumsy with ugly hacks (the additional symbol, using head and tail...) but at least it works...
[EDIT] I used some of the tricks shown by Daniel Sobral to shorten a bit my code. I kept my original design/algorithm to be distinctive... :-)