Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code Golf: Morris Sequence

GolfScript - 41 (extra credit: 40)

1{.p`n+0:c:P;{:|P=c{c`P|:P!}if):c;}%~1}do
{~.p`n+0:c:P;{:|P=c{c`P|:P!}if):c;}%1}do

What?
The procedure for getting the next number in the sequence: Convert the current number to a string, append a newline and loop over the characters. For each digit, if the previous digit P is the same, increment the counter c. Otherwise, add c and P to what will be next number, then update these variables. The newline we append allows the last group of digits to be added to the next number.

The exact details can be obtained examining the GolfScript documentation. (Note that | is used as a variable.)


Haskell: 115 88 85

import List
m x=do a:b<-group x;show(length b+1)++[a]
main=mapM putStrLn$iterate m"1"

This is the infinite sequence. I know it can be improved a lot - I'm fairly new to Haskell.

Bit shorter, inlining mapM and iterate:

import List
m(a:b)=show(length b+1)++[a]
f x=putStrLn x>>f(group x>>=m)
main=f"1"

Perl (46 characters)

$_="1$/";s/(.)\1*/length($&).$1/eg while print

Extra Credit (52 characters)

$_=(pop||1).$/;s/(.)\1*/length($&).$1/eg while print

Javascript 100 97

for(x=prompt();confirm(y=x);)for(x="";y;){for(c=0;y[c++]&&y[c]==y[0];);x+=c+y[0];y=y.substr(c--)}

Allows interrupting the sequence (by clicking "Cancel") so we don't lock the user-agent and peg the CPU. It also allows starting from any positive integer (extra credit).

Live Example: http://jsbin.com/izeqo/2


Perl, 46 characters

$_=1;s/(.)\1*/$&=~y!!!c.$1/ge while print$_,$/

Extra credit, 51 characters:

$_=pop||1;s/(.)\1*/$&=~y!!!c.$1/ge while print$_,$/

Mathematica - 62 53 50 chars - Extra credit included

Edit: 40 chars ... but right to left :(

Curiously if we read the sequence right to left (i.e. 1,11,12,1121, ..), 40 chars is enough

NestList[Flatten[Tally /@ Split@#] &, #2, #] &

That is because Tally generates a list {elem,counter} !

Edit: 50 chars

NestList[Flatten@Reverse[Tally /@ Split@#, 3] &, #2, #] &

Dissection: (read comments upwards)

NestList[               // 5-Recursively get the first N iterations
    Flatten@            // 4-Convert to one big list
       Reverse          // 3-Reverse to get {counter,element}
          [Tally /@     // 2-Count each run (generates {element,counter})
               Split@#, // 1-Split list in runs of equal elements
                 3] &,
                     #2,// Input param: Starting Number 
                     #] // Input param: Number of iterations

Edit: refactored

NestList[Flatten[{Length@#, #[[1]]} & /@ Split@#, 1] &, #2, #1] &

End edit ///

NestList[Flatten@Riffle[Length /@ (c = Split@#), First /@ c] &, #2, #1] &

Spaces not needed / added for clarity

Invoke with

%[NumberOfRuns,{Seed}]

My first time using "Riffle", to combine {1,2,3} and {a,b,c} into {1,a,2,b,3,c} :)


Here's my C# attempt using LINQ and first attempt at Code Golf:

C# - 205 194 211 198 bytes with extra credit (including C# boilerplate)

using System.Linq;class C{static void Main(string[]a){var v=a[0];for(;;){var r="";while(v!=""){int i=v.TakeWhile(d=>d==v[0]).Count();r+=i;r+=v[0];v=v.Remove(0,i);}System.Console.WriteLine(r);v=r;}}}

Readable version:

static void Main(string[] args)
{
    string value = args[0];
    for (;;)
    {
        string result = "";
        while (value != "")
        {
            int i = value.TakeWhile(d => d == value[0]).Count();
            result += i;
            result += value[0];
            value = value.Remove(0, i);
        }
        Console.WriteLine(result);
        value = result;
    }
}

Sample output:

11
21
1211
111221
312211
13112221
1113213211
...