构造一个置换器


9

对于这个挑战,您将要制作一个函数(您的函数可能是一个完整的程序),该函数将列表作为输入并返回该列表的排列。您的功能必须遵守以下要求。

  • 它必须是确定性的。

  • 将函数本身与变量进行组合的次数应该可以使列表包含其所有排列。

这是一个代码问题,因此答案将以字节计分,字节越少越好。

进一步规定

  • 你可以采取任何类型的列表,( ,,[Integer] 只要),因为它[String][[Integer]]

    • 可以为非空
    • 可以包含具有至少16个可能值的不同对象。(您不能使用Haskell [()]并声称您的函数是id
    • 可以包含重复的对象(无集合)
  • 您可以编写程序或函数,但必须遵守标准IO。


但是,S_n仅仅是对循环n<3
漏修女

@LeakyNun,它不要求生成对称组的单个排列:它要求一个next_permutation函数。
彼得·泰勒

仅置换0和1的列表就足够了吗?
xnor

我不确定我是否了解此限制的要点。如果允许布尔值列表,那么不允许在任何两个不同的项目上使用可迭代项有什么意义?
丹尼斯,

@丹尼斯你说的很好。我将不允许使用布尔值列表。或具有小于16个可能值的类型。
Ad Hoc Garf Hunter'7

Answers:


4

CJam(11个字节)

{_e!_@a#(=}

在线演示显示了一个包含四个重复元素的四元素列表的完整周期。

解剖

{      e# Define a block
  _e!  e#   Find all permutations of the input. Note that if there are duplicate
       e#   elements in the input then only distinct permutations are produced.
       e#   Note also that the permutations are always generated in lexicographic
       e#   order, so the order is independent of the input.
  _@a# e#   Find the index of the input in the list
  (=   e#   Decrement and get the corresponding element of the list
       e#   Incrementing would also have worked, but indexing by -1 feels less
       e#   wrong than indexing by the length, and makes this more portable to
       e#   GolfScript if it ever adds a "permutations" built-in
}

2

Mathematica + Combinatorica(内置程序包)34字节

19个字节来加载程序包,而15个字节用于功能。

<<"Combinatorica`";NextPermutation

用法:

%@{c, b, a}

没有内置的61字节

Extract[s=Permutations[Sort@#],Mod[s~Position~#+1,Length@s]]&

本来应该将Combinatorica完全合并到Mathematica中,但是我认为NextPermutation函数被忽略了。



2

C ++,42个字节

#include <algorithm>
std::next_permutation

此精确操作是C ++中的内置函数。


2
为什么后面要空格#include
Yytsi '17

2

的JavaScript(ES6),145 139 137 134 108个字节

感谢@Neil,节省了多达25个字节!

将输入作为字母字符数组。返回下一个排列作为另一个数组。

a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,a.concat(a.splice(x+1).sort()))

怎么样?

这是按字典顺序生成的,每次迭代处理以下四个步骤:

  1. 找到最大索引X,使a [X] <a [X + 1]

    a.map((v, i) => v < a[i + 1] ? (t = v, x = i) : ...)
  2. 找到大于X的最大索引Y使a [Y]> a [X]

    a.map((v, i) => v < a[i + 1] ? ... : y = i > x & v > t ? i : y)
  3. a [X]的值与a [Y]的值交换

    a[x] = a[y], a[y] = t
  4. 按从大到小的顺序从a [X +1]到最后一个元素(包括最后一个元素)对序列进行排序

    a.concat(a.splice(x + 1).sort())

例:

脚步

演示版


您不能排序而不是反转吗?另外,我认为v<a[i+1]&&(t=v,x=i)可以节省一个字节,并且您可以使用splice而不是2 来节省更多slice
尼尔

@Neil好抓住!
Arnauld

我认为我也可以合并两个maps,为112个字节:a=>(t=x=y=-1,a.map((v,i)=>v<a[i+1]?(t=v,x=i):y=i>x&v>t?i:y),a[x]=a[y],a[y]=t,t=a.splice(++x).sort(),a.concat(t))
尼尔(Neil)

我不得不承认,我认为自己没有用a.concat(a.splice(++x).sort()),否则我会尝试过的……
Neil

@尼尔谢谢!更新。(保存了另外4个字节,因为我们实际上不需要tconcat())。
Arnauld

1

果冻,6个字节

Œ¿’œ?Ṣ

按字典顺序降序循环排列。

在线尝试!

怎么运行的

Œ¿’œ?Ṣ  Main link. Argument: A (array)

Œ¿      Compute the permutation index n of A, i.e., the index of A in the
        lexicographically sorted list of permutations of A.
  ’     Decrement the index by 1, yielding n-1.
     Ṣ  Sort A.
   œ?   Getthe (n-1)-th permutation of sorted A.

1

C,161字节

实际的O(n)算法。

#define S(x,y){t=x;x=y;y=t;}
P(a,n,i,j,t)int*a;{for(i=n;--i&&a[i-1]>a[i];);for(j=n;i&&a[--j]<=a[i-1];);if(i)S(a[i-1],a[j])for(j=0;j++<n-i>>1;)S(a[i+j-1],a[n-j])}

用法示例:

int main(int argc, char** argv) {
    int i;
    int a[] = {1, 2, 3, 4};

    for (i = 0; i < 25; ++i) {
        printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]);
        P(a, 4);
    }

    return 0;
}

1

Python 2,154个字节

x=input()
try:exec'%s=max(k for k in range(%s,len(x))if x[%s-1]<x[k]);'*2%tuple('i1kjii');x[i-1],x[j]=x[j],x[i-1];x[i:]=x[:i-1:-1]
except:x.sort()
print x

在线尝试!


我认为这是较短的,因为它可以原位排列列表。
orlp

我尝试过,但是exec给了我函数一个种种错误
Dennis

0

果冻,10字节

ṢŒ!Q©i⁸‘ị®

在线尝试!

排序>所有排列>查找输入>添加1>索引到“所有排列


@PeterTaylor我已修复它。
Leaky Nun

有一些特定的内置置换功能(即,您可以做到Œ¿‘œ?Ṣ)。我不喜欢偷东西,因为同样的算法。
大公埃里克(Erik the Outgolfer)'17年

@EriktheOutgolfer对于包含重复项的输入可能有点混乱。
Leaky Nun

嗯...我想是的,我以前有一个适用于该版本的版本,但是您似乎在使用它Q。您仍然可以打高尔夫球ṢŒ!Qµi³‘ị
暴民埃里克(Erik the Outgolfer)'17年


0

PHP,117字节

将输入/输出作为小写字母的字符串列表

$a=str_split($s=$argn);rsort($a);if(join($a)!=$s)for($n=$s;($c=count_chars)(++$n)!=$c($s););else$n=strrev($s);echo$n;

在线尝试!

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.