按字母顺序排列的Fannkuch


14

Fannkuch是一个经典的基准程序。该名称来自德语“ Pfannkuchen”(煎饼),该算法类似于翻转煎饼叠。Fannkuch的数字序列形成如下:

以{1 ..... n}的排列为例,例如:{4,2,1,5,3}。取第一个元素(这里为4),并颠倒前四个元素的顺序:{5,1,2,4,3}。重复此操作,直到第一个元素为1,这样翻转就不再更改:{3,4,2,1,5},{2,4,3,1,5},{4,2,3, 1,5},{1,3,2,4,5}

您将要编写一个程序或函数来为字母字符串计算出类似于Fannkuch的序列。应该使用字母在字母表中的位置,而不是使用数字来指示每次应翻转列表中的多少元素。例如,前导c表示您应该颠倒前3个元素的顺序,而前导a表示序列已完成。

输入值

输入将通过stdin作为字符串或作为函数参数提供。该字符串将包含1到26个不同的小写字母。字符串将不包含字母,这些字母的等效索引将导致Fannkuch算法翻转比现有数量更多的元素。

输出量

程序或函数应返回或打印以输出通过应用Fannkuch算法产生的术语序列,直到a遇到前导为止,包括初始字符串。例如,如果输入为bca,则可以打印:

bca
cba
abc

打印的结果可以使用任何合理的分隔符-逗号,换行符等。可以选择任何空白。

再举一个例子,如果输入的是eabdc您可能会返回:

("eabdc"
 "cdbae"
 "bdcae"
 "dbcae"
 "acbde")

规则和计分

这是 -最短的程序获胜。不允许使用标准漏洞。

Answers:


11

Pyth,16个字节

.u+_<NJhxGhN>NJz

示范。

Pyth的reduce函数的“重复直到停止更改”功能在这里确实很方便。与.u累积归约函数一起使用,以输出所有结果。reduce的主体尽可能幼稚,但是我找不到更好的东西。


5

T-SQL,213字节

当然,由于SQL确实很大,但是这样做很有趣。使用递归CTE查询创建为内联表函数。

CREATE FUNCTION F(@ CHAR(26))RETURNS TABLE RETURN WITH R AS(SELECT @ S UNION ALL SELECT CAST(STUFF(S,1,ASCII(LEFT(S,1))-96,REVERSE(LEFT(S,ASCII(LEFT(S,1))-96)))AS CHAR(26))FROM R WHERE LEFT(S,1)<>'a')SELECT*FROM R

展开式

CREATE FUNCTION F(@ CHAR(26))
RETURNS TABLE 
RETURN WITH R AS(
    SELECT @ S            -- Initial string as an anchor for the recursion
    UNION ALL 
    SELECT CAST(
        STUFF(                                    -- Stuff into 
            S,                                    -- string S
            1,                                    -- from position 1
            ASCII(LEFT(S,1))-96,                  -- to index value of first char
            REVERSE(LEFT(S,ASCII(LEFT(S,1))-96))  -- the reverse of the index first chars
            )
        AS CHAR(26))
    FROM R 
    WHERE LEFT(S,1)<>'a'  -- recurse until first char is a
)SELECT*FROM R

用法如下

SELECT * FROM F('eabdc')
S
--------------------------
eabdc                     
cdbae                     
bdcae                     
dbcae                     
acbde                     

(5 row(s) affected)

4

CJam,22个字节

这是一个匿名函数,它在堆栈上获取一个字符串,并在堆栈上返回一个字符串列表。

{_,{_0='`-/(W%\+s_}*]}

在这里在线尝试


3

Python 2,59个字节

def p(l):
 print l;o=ord(l[0])-97
 if o:p(l[o::-1]+l[o+1:])

我想这是一个相当简单的答案。使用递归和Python的slice语法。呼叫为:p('eabdc')


3

SAS,131个字节

sub a(s$);outargs s;put s;do while(b ne 1);b=rank(char(s,1))-96;substr(s,1,b)=reverse(substr(s,1,b));if b>1 then put s;end;endsub;

FCMP调用例程。在下面不再赘述(我强烈建议您进行额外的检查,如果FCMP例程进入无限循环,SAS会崩溃)。


options cmplib=work.funcs;
proc fcmp outlib=work.funcs.funcs;
  sub a(s$);
    outargs s;
    put s=;
    do while (b ne 1 and z<1e5);
        b=rank(char(s,1))-96;
        substr(s,1,b) = reverse(substr(s,1,b));
        if b>1 then put s=;
        z+1;
    end;
  endsub;
quit;

辛苦了 我们proc fcmp在这里没有很多。
Alex A.

2

Haskell,78个字节

f l@(h:_)|h=='a'=[l]|1<2=l:f(reverse(take d l)++drop d l)where d=fromEnum h-96

用法: f "eabdc" -> ["eabdc","cdbae","bdcae","dbcae","acbde"]


考虑使用splitAt-您可以将其减少到71个字节!
MtnViewMark

@MtnViewMark好吧,我似乎有完全相同的算法,低至68个字节
骄傲的haskeller 2015年

2

K5,21个字节

{(|v#x),(v:*x-96)_x}\

@JohnE节省了5个字节,而通过重新排列表达式又节省了5个字节。

我认为这是K首次击败CJam!

27字节版本

(~97=*){(|v#x),(v:-96+*x)_x}\

如果使用定点形式的“扫描”,则可以使此操作更短。
JohnE

@JohnE谢谢!我没有意识到,当第一个字母是a,字符串不会改变。
kirbyfan64sos

0

哈斯克尔,68

f l@(x:_)|x<'b'=[l]|(x,y)<-splitAt(fromEnum x-96)l=l:f(reverse x++y)

我想到的任何更复杂的策略都会占用更多字节。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.