代码高尔夫: Morris序列

46

挑战

以字符计数最短的代码输出 莫里斯数字序列,也称为 外观数列,序列的前几项如下:

1, 11, 21, 1211, 111221, 312211, ...

你可以无限生成这个序列(也就是说,你不必生成特定数量的数字)。

输入/输出期望

程序不需要接受任何输入(但如果能接受输入并提供从任意起始点或数字开始的选项,则加分)。至少,你的程序必须从 1 开始。

输出至少应该是序列本身:

1
11
21
1211
111221
312211
...

额外加分

如果你想要获得额外的加分,你需要做如下操作:

$ morris 1
1
11
21
1211
111221
312211
...

$ morris 3
3
13
1113
3113
132113
...

1
输入和输出的期望是什么?单个值,单个输出吗?特定次数的迭代? - Mike Clark
1
我认为如果你用“无限地”(模糊、不清楚)替换为“无穷尽地”(无限的,没有边界),它会更清晰。至于关闭问题:习惯就好了。在SO上,“代码高尔夫”问题是一个灰色区域。 - BalusC
3
输出应该是 [13, 1113, 3113...] 还是 [3, 13, 1113, 3113...]? - Instantsoup
@Bart - 我喜欢看到我的帖子被引用!很高兴看到人们仍然在帮助新手。 - Chris Lutz
6
@Nakilon,我想各种不同的方法(如下)并不意味着有多种方法可供选择。感谢您精彩的见解。 - Vivin Paliath
显示剩余9条评论
41个回答

0

Lua,114字节(含奖励)

简化版:

x=arg[1]while 1 do print(x)i=1 y=''while i<=#x do a=x:sub(i,i)s,e=x:find(a..'+',i)y=y..e+1-s..a;i=e+1 end x=y end

适当格式化:

x=arg[1]
for k=1,10 do
    print(x)
    i=1
    y=''
    while i <= #x do
        a=x:sub(i,i)
        s,e=x:find(a..'+',i)
        y=y..e+1-s ..a
        i=e+1
    end
    x=y
end

0

C++,264

#include <iostream>
#include <sstream>
#include <string>
using namespace std;int main(){string l="1\n";for(;;){ostringstream o;int e=1;char m;cout<<l;for(int i=1;i<l.size();i++){m=l[i-1];if(l[i]==m)e++;else if(e){if(m!='\n')o<<e<<m;e=1;}}l=o.str()+'\n';}return 0;}

带有适当缩进:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int main()
{
    string l="1\n";
    for(;;)
    {
        ostringstream o;
        int e=1;
        char m;
        cout<<l;
        for(int i=1; i<l.size(); i++)
        {
            m=l[i-1];
            if(l[i]==m)
                e++;
            else if(e)
            {
                if(m!='\n')
                    o<<e<<m;
                e=1;
            }
        }
        l=o.str()+'\n';
    }
    return 0;
}

示例输出:

matteo@teoubuntu:~/cpp$ g++ morris.cpp -O3 -o morris.x && ./morris.x | head1
11
21
1211
111221
312211
13112221
1113213211
31131211131221
13211311123113112211

C++,276分(含额外加分)

#include <iostream>
#include <sstream>
#include <string>
using namespace std;int main(){string l;getline(cin,l);for(;;){ostringstream o;int e=1;char m;l+='\n';cout<<l;for(int i=1;i<l.size();i++){m=l[i-1];if(l[i]==m)e++;else if(e){if(m!='\n')o<<e<<m;e=1;}}l=o.str();}return 0;}

带有适当缩进:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int main()
{
    string l;
    getline(cin,l);
    for(;;)
    {
        ostringstream o;
        int e=1;
        char m;
        l+='\n';
        cout<<l;
        for(int i=1; i<l.size(); i++)
        {
            m=l[i-1];
            if(l[i]==m)
                e++;
            else if(e)
            {
                if(m!='\n')
                    o<<e<<m;
                e=1;
            }
        }
        l=o.str();
    }
    return 0;
}

示例输出:

matteo@teoubuntu:~/cpp$ g++ morris.cpp -O3 -o morris.x && ./morris.x | head
7754 <-- notice: this was inserted manually
7754
271514
121711151114
1112111731153114
31123117132115132114
13211213211711131221151113122114
11131221121113122117311311222115311311222114
3113112221123113112221171321132132211513211321322114
132113213221121321132132211711131221131211132221151113122113121113222114
111312211312111322211211131221131211132221173113112221131112311332211531131122211311123113322114

0

c# 315 236 228

第一次尝试编程高尔夫


static void Main(string[]args)
    {string o,s="1";int l=11;while(l-- >0)
    {Console.WriteLine(s);o="";while(s!=""){var c=s.Substring(0,1);int i=Regex.Match(s,"("+c+"*)").Length;o+=i.ToString()+c;s=s.Substring(i);}s=o;}}

这是带有换行和空格的源代码 >8.9999999999


static void main( string[] args )
    {
        string sp = "1";
        string ou = "";
        int It = 11;
        while ( It-- > 0 )
        {

            Console.WriteLine(sp);
            ou = "";
            while ( sp != "" )
            {
                var c = sp.Substring(0, 1);
                int i = Regex.Match(sp, "(" + c + "*)").Length;
                ou += i.ToString() + c;
                sp = sp.Substring(i);

            }
            sp = ou;
        }
    }

额外加分

static void Main(string[]a)
{string o,s=a[0];int l=11;while(l-- >0)
{Console.WriteLine(s);o="";while(s!=""){var c=s.Substring(0,1);int i=Regex.Match(s,"("+c+"*)").Length;o+=i.ToString()+c;s=s.Substring(i);}s=o;}}

0

C#,140个工作字符(177 171个带样板文件)

class C{static void Main(){var x="1\n";for(;;){System.Console.Write(x);var y="";for(int n,i=0;i<x.Length-1;y+=n+""+x[i],i+=n)n=x[i+1]!=x[i]?1:x[i+2]!=x[i]?2:3;x=y+"\n";}}}

这个漏洞利用了康威的观察结果(如果我没记错),即序列中不会出现大于3的数字。

        var x = "1\n";
        for (; ; )
        {
            Console.Write(x);
            var y = "";
            var i = 0;
            while (i < x.Length - 1)
            {
                var n = x[i + 1] != x[i] ? 1 : x[i + 2] != x[i] ? 2 : 3;
                y += n + "" + x[i];
                i += n;
            }
            x = y + "\n";
        }

0

Delphi,163字节(加上额外的166字节)

对 Andreas Rejbrand 版本进行了显著的改进。很好使用 str() 函数时不检查参数类型,否则我就必须将整数 (s) - 整数 (u) 进行转换。

var q,t,k:string;s,u:pchar;label l,z;begin t:='1';l:writeln(t);q:=t;s:=@q[1];
t:='';z:u:=s;while s^=u^do Inc(s);str(s-u,k);t:=t+k+u^;if s^=#0then goto l;
goto z;end.

如果需要额外的操作,请将 t:='1'; 更改为 t:=readln;


1
由于0 = 00,因此您可以轻松地节省一个字符。 - Andreas Rejbrand

0

Javascript: 87

这是受BoltClock的代码启发,以及我自己的PHP尝试而来。

for(a="1";!(c="");alert(a),a=c)for(j=0,x=1;a[j];j++)a[j]==a[j+1]?x++:(c+=x+a[j])&&(x=1)

Javascript 带额外内容:92

for(a=prompt();!(c="");alert(a),a=c)for(j=0,x=1;a[j];j++)a[j]==a[j+1]?x++:(c+=x+a[j])&&(x=1)

美化:

// Start with a=1, an set c to "" every start of the loop
// alert a and set a=c at the end of a loop
for (a = "1"; !(c = ""); alert(a), a = c)

  // Set iterator j to 0, set counter x to 1 at the initialisation
  // detect if a[j] exists at the start of the loop and incremement j at the end
  for (j = 0, x = 1; a[j]; j++)

    // check if the jth and (j+1)th characters are equal
    // if so, increment x,
    // if not, the end of a row is found, add it to c and set x to 1 again
    a[j] == a[j + 1] ? x++ : (c += x + a[j]) && (x = 1)

0

Clojure 111个字符

(loop[a"1"](pr a)(let[x(reduce(fn[a b](str a(count(first b))(nth b 1)))(str)(re-seq #"(.)\1*" a))](recur x)))

奖励 119 个字符

(loop[a(read-line)](pr a)(let[x(reduce(fn[a b](str a(count(first b))(nth b 1)))(str)(re-seq #"(.)\1*" a))](recur x)))

0

285 248个字符是我在C#中能做到的最好结果(这还没有包括额外内容!)

编辑:这也是我的第一个代码高尔夫比赛.. 做得很愉快:D

static void Main(){string s="1",x=s;for(;;){char[]c=x.ToCharArray();char d=c[0];x="";int a=0;for(inti=0;i<=c.Length;i++){char q;if(i!=c.Length)q=c[i];else q='0';if (d != q){x+=a.ToString();x+=d.ToString();d=q;a=1;}else a++;}Console.WriteLine(x);}}

易读的代码:

using System;
class Program
{
    static void Main()
    {
        string startPoint = "1";
        string currentPoint = startPoint;
        while (true)
        {
            char[] currentPointAsCharArray = currentPoint.ToCharArray();
            char previousCharacter = currentPointAsCharArray[0];
            currentPoint = "";
            int countOfCharInGroup = 0;
            for(int i=0;i<=currentPointAsCharArray.Length;i++)
            {
                char c;
                if (i != currentPointAsCharArray.Length)
                    c = currentPointAsCharArray[i];
                else
                    c = '0';
                if (previousCharacter != c)
                {
                    currentPoint += countOfCharInGroup.ToString();
                    currentPoint += previousCharacter.ToString();
                    previousCharacter = c;
                    countOfCharInGroup = 1;
                }
                else
                    countOfCharInGroup++;
            }
            Console.Write(currentPoint + "\n");
        }
    }
}

0

Scala - 97个字符

受@BalusC卓越回答的启发:

def m(s:String){println(s);m((""/:(s split"(?<=(.)(?!\\1))")){(a,s)=>a+s.size+s(0)})};m(args(0))

0

J,61个字符

J: las=: ,@((# , {.);.1~ 1 , 2 ~:/\ ])&.(10x&#.inv)@]^:(1+i.@[)

例子:

10 las 1
1 11 21 1211 111221 312211 13112221 1113213211 31131211131221 13211311123113112211 11131221133112132113212221

请注意,结果是一个实际的数字序列(与其他语言中给出的文本解决方案相比)。
源代码在这里:http://rosettacode.org/wiki/Look-and-say_sequence#J

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接