漂移排序数组


25

Driftsort是“排序”数组的一种简单方法。它通过“滑动”或“旋转”数组中的元素来工作,直到对数组进行排序或对数组进行排序失败为止。

让我们来看两个例子。首先,考虑array [10, 2, 3, 4, 7]。由于数组未排序,因此将其旋转一次。(这可以在任何方向上发生,只要它保持相同的方向即可。)然后,数组变为:

[7, 10, 2, 3, 4]

这没有排序,因此我们再次旋转。

[4, 7, 10, 2, 3]

然后再次:

[3, 4, 7, 10, 2]

最后一次:

[2, 3, 4, 7, 10]

并排序!因此,该数组[10, 2, 3, 4, 7]是可漂移排序的。为了清楚起见,这是数组的所有旋转:

[10, 2, 3, 4, 7]
[7, 10, 2, 3, 4]
[4, 7, 10, 2, 3]
[3, 4, 7, 10, 2]
[2, 3, 4, 7, 10]

现在考虑数组[5, 3, 9, 2, 6, 7]。看一下它的旋转:

[5, 3, 9, 2, 6, 7]
[7, 5, 3, 9, 2, 6]
[6, 7, 5, 3, 9, 2]
[2, 6, 7, 5, 3, 9]
[9, 2, 6, 7, 5, 3]
[3, 9, 2, 6, 7, 5]

这些数组均未排序,因此该数组[5, 3, 9, 2, 6, 7]不可漂移排序。


目标给定一个非空的整数数组/列表作为程序/函数的输入,请对输入执行漂移排序并将其输出,或者如果无法对它进行漂移排序,则输出假值(空数组/列表)。整数与您的语言的最大/最小绑定,但是最大必须为255,最小为0。

您可以使用内置的排序方法,但不能使用内置的方法来解决挑战。

这是一个,因此是最短的程序,以字节为单位。

测试用例

input => output
[1] => [1]
[5, 0, 5] => [0, 5, 5]
[3, 2, 1] => false
[0, 9, 3] => false
[1, 2, 3, 4] => [1, 2, 3, 4]
[4, 1, 2, 3] => [1, 2, 3, 4]
[0, 2, 0, 2] => false
[5, 3, 9, 2, 6, 7] => false
[0, 0, 0, 0, 0, 0, 0] => [0, 0, 0, 0, 0, 0, 0]
[75, 230, 30, 42, 50] => [30, 42, 50, 75, 230]
[255, 255, 200, 200, 203] => [200, 200, 203, 255, 255]

5
一种检查列表是否可漂移的简单方法是if sorted(l)是的连续子列表l+l
xnor

只是要澄清一下:如果我们的语言支持负整数,则它们可以出现在输入中,是吗?
丹尼斯

@丹尼斯是正确的。
Conor O'Brien

这不应该被称为shiftsort吗?
Filip Haglund

@FilipHaglund我曾想过要调用它,但是它可能与shift删除数组第一个元素的操作引起混淆。
Conor O'Brien

Answers:


9

果冻,6 个字节

ṙỤċṢȧṢ

在线尝试!验证所有测试用例

怎么运行的

ṙỤċṢȧṢ  Main link. Argument: A (list)

 Ụ      Grade up; return the indices of A, sorted by their corresponding values.
ṛ       Rotate A by each index, yielding the list of all rotations.
   Ṣ    Yield A, sorted.
  ċ     Count the number of times sorted(A) appears in the rotations.
        This gives 0 if the list isn't driftsortable.
    ȧṢ  Logical AND with sorted(A); replaces a positive count with the sorted list.

1
Ahem,UTF8的19个字节。
rsaxvc '16

11
Jelly有一个自定义代码页,可将它理解为单个字节的256个字符中的每一个编码。(使用UTF-8 btw是16个字节。)
Dennis

3
@Dennis:您应该在所有Jelly提交的内容中复制/粘贴此内容,以防止我们(即以前不知道这一点的人)发表相同的评论?;)
Olivier Dulac

18

红宝石,33岁

->a{a.any?{a.sort==a.rotate!}&&a}

a.any?对数组中的每个元素最多触发一次,除了一旦数组突变为已排序状态即停止(并返回true)。如果发生这种情况,我们将返回变异数组。否则,我们返回返回的假值any?


1
这非常聪明,尤其是就地旋转。干得好!
Alex A.

las,我对Ruby的回答已被击败。+1
价值墨水

3
嗯,是的,古老的“排序直到您知道它是否可以排序”技术为止。
corsiKa '16

14

Python 2,51字节

lambda l:sorted(l)*(map(cmp,l[-1:]+l,l).count(1)<3)

不必打扰旋转。取而代之的是,对列表进行排序,然后通过检查环化列表的连续元素中最多是否有一个减数来查看原始文档是否可以进行漂移排序。计数是<3因为在末尾map填充了较短的列表None,从而增加了虚假的减少。


2
[1, 3, 2, 4]连续元素之间只有一个减少,但不是漂移排序的。
尼尔

1
@尼尔哦拍。
xnor

@Neil我认为这可以解决。你能看看吗?
xnor

10
我们也是<3
的最爱

我不能说我是Python方面的专家,但是假设这样做<3是合理的,以避免避免精确旋转列表。
尼尔

10

Pyth,9个字节

*SQ}SQ.:+

说明:

           - Q = eval(input())
         + -    Q+Q
       .:  -   sublists(^)
   }       -  V in ^
    SQ     -   sorted(Q)
*SQ        - ^ * sorted(Q) (return sorted(Q) if ^ True)

在这里尝试!

或使用测试套件!


1
我认为您的意思是的子字符串(子列表).:。组合将包括不连续的元素。
xnor

6

Matlab,61 47 41字节

感谢@Suever -6个字节!

@(a)sort(a)+0*min(strfind([a,a],sort(a)))

如果strfind([a,a],sort(a))尝试查找已排序的输入向量作为未排序的“子字符串”,则会附加到其自身。如果为true,则输入是可漂移排序的,并且我们得到一个长度为2的向量,否则,我们得到一个空向量。min只是将其转换为数字/空向量。将排序后的向量添加到0只会显示它,将其添加到空向量会抛出错误。


子字符串检查是否[2, 3]不属于的子列表[12, 34]
xnor

是的,每个整数数组也可以解释为字符串,无论数字有多大,每个数字都被视为一个字符。
瑕疵的2016年

@flawr我的解释是,它strfind可以直接与数字一起使用,不仅可以与字符一起使用(即使没有记录)。如果将数字解释为字符,则将它们限制为65535(例如尝试+char(1e5)
Luis Mendo

@LuisMendo是的,它甚至适用于浮点数。请注意,大于65535的数字在被视为字符串的一部分时只会显示为空格。
瑕疵的

5

朱莉娅71 66 52字节

x->(y=sort(x))∈[circshift(x,i)for i=1:endof(x)]&&y

这是一个匿名函数,它接受一个数组并返回一个数组或一个布尔值。要调用它,请将其分配给变量。

对于输入数组x,我们构造x的所有旋转的集合,并检查排序后的版本x是否为该列表的元素。如果是,则返回已排序的x,否则返回false。

感谢Dennis,节省了19个字节!


4

,15 +1 = 17 16字节

嗯,其他高尔夫语言正在把它吹出水面。但是,由于我已经写过了...

L#gI$<gPBPOgYgy

将输入作为以空格分隔的命令行参数。需要-p或另一个数组格式标志来清晰显示结果,而不是串联显示。错误的情况将输出一个空字符串,该字符串可通过结尾的换行符看到。

                 Implicit: g is array of cmdline args; y is empty string
L#g              Loop len(g) times:
         POg       Pop the first item from g
      gPB          Push it onto the back of g
    $<             Fold on < (true if g is now sorted)
   I        Yg     If true, yank g into y
              y  Autoprint y

4

JavaScript(ES6),72 70 65字节

a=>a.map(y=>{c+=x>y;x=y},x=a.slice(c=-1))|c<1&&a.sort((a,b)=>a-b)

0失败时返回。以前的85 83 80字节版本避免了调用sort

a=>a.map((y,i)=>{x>y&&(c++,j=i);x=y},x=a.slice(c=-1))|c<1&&a.splice(j).concat(a)

编辑:保存2个字节的初始化c,以-1代替0。从切换reducemap,节省了5个字节。


查看编辑内容;)
Conor O'Brien

呼叫号码排序不正确。检查样品[10, 2, 3, 4, 7]
Qwertiy '16

此代码还failes 3个测试:[1][0, 0, 0, 0, 0, 0, 0][75, 230, 30, 42, 50]
Qwertiy '16

@Qwertiy对不起sort,造成第三次测试失败的疏忽。其他两个测试失败是由于我过度打高尔夫球造成的;我已还原到以前的版本。
尼尔


3

雪人1.0.2,27字节

((}#AsO|##aC,as|aLNdE`aR*))

这是一个子例程,用于从当前永久对象输入和输出当前永久对象。

在线尝试!

((                       ))  subroutine
  }                          set our active variables b, e, and g:
                              .[a] *[b] .[c]
                              .[d]      *[e]    (* represents an active variable)
                              .[f] *[g] .[h]
   #                         store the input in variable b
    AsO                      sort in-place
       |                     swap b with g; now sorted input is in g
        ##                   store the input again in b and e
          aC                 concat; now the input doubled is in b and e is empty
            ,                swap e/g; now b has 2*input and e has sorted input
             as              split 2*input on sort(input) and store result in g
               |             bring the result up to b (we no longer care about g)
                aLNdE        take length and decrement; now we have 0 in b if the
                               array is not driftsortable and 1 if it is
                     `aR     repeat e (the sorted array) b times:
                               if b is 0 (nondriftsortable), returns [] (falsy)
                               otherwise (b=1), returns sorted array unchanged
                        *    put this back into the permavar

3

MATL,13 12 10 9字节

SGthyXfa*

@flawr答案的想法相同,我们劫持了strfindXf)以在输入的两个副本的串联中找到输入的排序版本。

在线尝试!

说明

        % Implicitly get input
S       % Sort the input
Gth     % Explicitly grab the input again and concatenate with itself
y       % Copy the sorted version from the bottom of the stack
Xf      % Look for the sorted version as a subset
a       % Gives a 1 if there were matches and 0 otherwise
*       % Multiply by the sorted array. Yields all zeros for no match and the
        % sorted array when a match was found
        % Implicitly display the stack contents

1
你不能删除g吗?或替换nga
路易斯·门多

@LuisMendo不能仅用一个替换,n因为n可能是> 1. a 绝对可以。我认为有更好的方法。谢谢!
Suever 2016年

3

朱莉娅,33个字节

x->sum(diff([x;x]).<0)<3&&sort(x)

在线尝试!

怎么运行的

这样可以将阵列X与自身和计数对属于的顺序出的数量,即连续的子阵列的数目[A,B]为其中b - a <0时。如果cx本身的无序对的数量,并且如果x的最后一个元素大于第一个元素,则t1,则将返回2c + tsum

数组x是可漂移排序的iff (c,t)=(1,0)x必须旋转到唯一的无序对中的较小值),(c,t)=(0,1)x已排序)或(c,t)=(0,0)x已排序且所有元素均相等),当2c + t <3时为真。


3

的Javascript ES6,48 45 43个字符

x=>~(x+[,x]).indexOf(x.sort((a,b)=>a-b))&&x

测试:

f=x=>~(x+[,x]).indexOf(x.sort((a,b)=>a-b))&&x
;`[1] => [1]
[5, 0, 5] => [0, 5, 5]
[3, 2, 1] => false
[0, 9, 3] => false
[1, 2, 3, 4] => [1, 2, 3, 4]
[4, 1, 2, 3] => [1, 2, 3, 4]
[0, 2, 0, 2] => false
[5, 3, 9, 2, 6, 7] => false
[0, 0, 0, 0, 0, 0, 0] => [0, 0, 0, 0, 0, 0, 0]
[75, 230, 30, 42, 50] => [30, 42, 50, 75, 230]
[255, 255, 200, 200, 203] => [200, 200, 203, 255, 255]`
.split`
`.map(t => t.replace(/^(.*) => (.*)$/, "f($1)+'' == $2")).every(eval)

我认为您可以使用来节省两个字节,而在您的情况下可以使用来节省(x+[,x])另一个字节。~1+
尼尔

@ user6188402,是的,谢谢。
Qwertiy

2

Brachylog,39个字节

l:0re:?{[0:L],!L.|rh$(L,?h-1=:L:1&.}.o.

我真的需要添加一个可选参数来$( - circular permute left进行多次置换……这将是13个字节。在Prolog中实施稳定的新编译器后,将等待。

说明

l:0re                                     I = a number between 0 and the length of Input
     :?{[0:L],!L.|rh$(L,?h-1=:L:1&.}      All this mess is simply circular permutating the
                                          input I times
                                    .o.   Unify the Output with that circular permutation
                                          if it is sorted, else try another value of I

2

Ruby,47个字节

递归函数。返回nil输入数组是否不能进行漂移排序。

f=->a,i=0{a.sort==a ?a:a[i+=1]?f[a.rotate,i]:p}

2

CJam,17 13字节

感谢Dennis节省了4个字节。

{_$\_+1$#)g*}

一个未命名的块(函数),它接收并返回一个列表。

测试套件。

说明

本质上,这使用了xnor的观察,即如果其可排序,则排序后的列表会出现在原始列表的两倍中:

_$   e# Duplicate input and sort.
\_+  e# Get other copy and append to itself.
1$   e# Copy sorted list.
#    e# Find first position of sorted list in twice the original,
     e# of -1 if it's not found.
)g   e# Increment and take signum to map to 0 or 1.
*    e# Repeat sorted array that many times to turn it into an empty
     e# array if the input was not drift sortable.

@Dennis哦,看来我们是独立提出的。不过谢谢 :)
Martin Ender

2

C ++ 14,242个字符

#include<iostream>
#include<vector>
#include<algorithm>
#define b v.begin()
using namespace std;int main(){vector<int>v;int x,n=0;for(;cin>>x;++n)v.push_back(x);for(x=n;x--;rotate(b,b+1,b+n))if(is_sorted(b,b+n)){for(x:v)cout<<x<<' ';return 0;}}

如果我不能将输出留空,则为252个字符http://ideone.com/HAzJ5V

#include<iostream>
#include<vector>
#include<algorithm>
#define b v.begin()
using namespace std;int main(){vector<int>v;int x,n=0;for(;cin>>x;++n)v.push_back(x);for(x=n;x--;rotate(b,b+1,b+n))if(is_sorted(b,b+n)){for(x:v)cout<<x<<' ';return 0;}cout<<'-';}

非高尔夫版本http://ideone.com/Dsbs8W

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

#define b v.begin()

int main()
{
  vector <int> v;
  int x, n=0;

  for(;cin>>x;++n)
    v.push_back(x);

  for(x=n;x--;rotate(b,b+1,b+n))
    if(is_sorted(b,b+n))
    {
      for(x:v) cout<<x<<' ';
      return 0;
    }

  cout << '-';
}

PS:基于@MichelfrancisBustillos的想法


2

Java 7,207字节

int[]D(int[]i){int x,z;z=x=-1;int[]d=new int[i.length];while(++x<i.length)if(i[x]>i[(x+1)%i.length])if(z<0)z=(x+1)%i.length;else return null;if(z<0)z=0;x=-1;while(++x<d.length)d[x]=i[z++%i.length];return d;}

详细 尝试这里

// driftsort in ascending-order
int[] D(int[]i)
{
    int x = -1,z = -1;
    int[] d = new int[i.length];

    while ((++x) < i.length)
    {
        if (i[x] > i[(x+1)%i.length])
        {
            if(z < 0) z = (x+1)%i.length;
            else return null; // not driftsortable
        }
    }

    if(z < 0) z = 0;
    x = -1;
    while ((++x) < d.length)
    {
        d[x] = i[(z++)%i.length];
    }

    return d;
}

2

Java 175

将输出打印f为以空格分隔的值,或打印为假值。

void d(int[]a){String s;for(int v,w,x=-1,y,z=a.length;++x<z;){v=a[x];s=""+v;for(y=0;++y<z;v=w){w=a[(x+y)%z];if(v>w){s="f";break;}s+=" "+w;}if(y==z)break;}System.out.print(s);}

遍历整数数组的所有组合,直到找到有效序列或组合用完。不会修改数组,而是将driftsorted序列存储为以空格分隔的字符串。

更具可读性:

void driftsort(int[]array){
    String str;
    for(int previous,current,x=-1,y,len=array.length;++x<len;){
        previous=array[x];
        s=""+previous;
        for(y=0;++y<len;previous=current){
            current=array[(y+x)%len];
            if(previous>current){
                str="false";
                break;
            }
            str+=" "+current;
        }
        if(y==len)break;
    }
    System.out.print(str);
}

在线尝试


2

C,105字节

i,s;main(c,v)char**v;{c--;while(i++<c)if(atoi(v[i])>atoi(v[i%c+1]))c*=!s,s=i;while(--i)puts(v[s++%c+1]);}

它将输入整数作为单独的命令行参数接受,并将输出列表打印为每行一个整数。

如果列表不是可漂移排序的,则该程序由于浮点异常而过早退出,因此其空输出表示一个空列表。

验证

$ gcc -o driftsort driftsort.c 2>&-
$ ./driftsort 1 | cat
1
$ ./driftsort 5 0 5 | cat
0
5
5
$ ./driftsort 3 2 1 | cat
$ ./driftsort 0 9 3 | cat
$ ./driftsort 1 2 3 4 | cat
1
2
3
4
$ ./driftsort 4 1 2 3 | cat
1
2
3
4
$ ./driftsort 0 2 0 2 | cat
$ ./driftsort 5 3 9 2 6 7 | cat
$ ./driftsort 0 0 0 0 0 0 0 | cat
0
0
0
0
0
0
0
$ ./driftsort 75 230 30 42 50 | cat
30
42
50
75
230
$ ./driftsort 255 255 200 200 203 | cat
200
200
203
255
255

2

红宝石,28岁

->a{(a*2*?,)[a.sort!*?,]&&a}

返回排序后的数组,或者返回nil(输入值是伪造的)如果输入不是可漂移排序的。


2

Python,53个字节

s,N=sorted,lambda x:s(x)*(str(s(x))[1:-1]in str(x+x))

如果要对此进行测试,请转到https://www.repl.it/languages/python3并复制并粘贴:

s,N=sorted,lambda x:s(x)*(str(s(x))[1:-1]in str(x+x))
print(N([1,2,3,4,5,0]))

怎么运行的:

  • s是存储对sorted列表进行排序的python函数的变量
  • N 是主要功能
  • 输入列表排序: s(x)乘以列表是否可漂移排序str(s(x))[1:-1]in str(x+x)(由于@xnor)
    • 这行得通,因为 [1,2,3,4]*false结果是一个空列表[]
    • [1,2,3,4]*true导致[1,2,3,4]

1
在Python 2中,您可以将其缩短lambda x,s=sorted:(`s(x)`[1:-1]in`x+x`)*s(x)为44个字节。
丹尼斯

1

Python,83个字节

def f(l):g=sorted(l);return g if any(l[x:]+l[:x]==g for x in range(len(l)))else 1>2

这让其他python答案感到羞耻,但无论如何我还是应该发布它。我真的不喜欢

range(len(l)))

部分。有没有更快的方法来遍历列表?


1
数量不多,但是l.append(l.pop(0))or g==l for _ in l比range-len方法节省了一个字节。使用a lambda将节省14个额外的字节。
丹尼斯

1

MATLAB / Octave,118字节

function r(a)
i=0
while (~issorted(a) && i<length(a))
    a=a([2:end 1]),i=i+1
end
if issorted(a)
    a
else
    0
end

2
我认为您可以通过在一行上编写所有内容并使用来节省一些字节input('')。同时避免不必要的空格和括号!然后,您可以通过先定义再次释放一些字节f=@issorted
瑕疵的2016年

1

PowerShell v2 +,87个 80字节

param($a)0..($a.length-1)|%{if($a[$_-1]-gt$a[$_]){$c--}};(0,($a|sort))[++$c-ge0]

$a逐步检查输入列表,检查每个成对元素(包括最后一个和第一个),以查看是否存在多个递减的对。如果特定对减少,则我们递减$c0根据$c末尾的值输出排序列表或单个元素。如果存在多个“坏”对,则它们++$c仍将为负,否则至少为0,因此选择伪三元组的第二个元素($a|sort)。

我看到xnor做过类似的事情,但是我是独立提出的。


1

因子,47字节

[ dup dup append [ natural-sort ] dip subseq? ]

将序列连接到自身上,然后检查原始序列的排序表示形式是否为子序列。


1
这听起来像是一种哲学上的:句:dup dup append \\ natural sort \\ dip subseq?甚至符合4-4-3模式:)
Akiiino

@Akiiino:D无点语言是如此富有诗意。

1

C ++,313个359 370字节

@Qwertiy对此大声喊叫,以使其正常工作并教我一些出色的高尔夫方法!

打高尔夫球:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){vector<int> v;int x,c=0,s=0,y;while(cin>>x)v.push_back(x);do if(rotate(v.begin(),v.begin()+1,v.end()),c++,is_sorted(v.begin(),v.end()))s=1;while(!s&c<=v.size());if(s)for(y=0;y<v.size();y++)cout<<v[y]<<" ";else cout<<"False";}

取消高尔夫:

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main(){
  vector <int> v;
  int x, c=0, s=0, y;

  while(cin>>x)
    v.push_back(x);

  do 
    if (
      rotate(v.begin(),v.begin()+1,v.end()),
      c++,
      is_sorted(v.begin(),v.end())
    ) s = 1;
  while(!s & c <= v.size());

  if (s)
    for(y=0; y<v.size(); y++)
      cout<<v[y]<<" ";
  else
    cout<<"False";
}

1
打高尔夫球不仅是在移动空间。using namespace std;是20字符,而std::6倍是30。- bool s = False;为什么不=0呢?你可以放下return 0;。为什么括号在这里!s&&(c<=v.size())?花括号和没有逗号...
Qwertiy '16

哇谢谢!编程类已经习惯了很多东西(如std::return 0;)。我真的需要更好地开始检查我的程序。
Michelfrancis Bustillos

1
还有一组错误。为什么要读到零,然后将零放入数据中?为什么要输出到包括尺寸在内的尺寸?为什么TrueFalse而不是truefalseideone.com/kVTI25-您的版本,ideone.com / y8s44A-已修复并准备打高尔夫球。
Qwertiy '16

再次感谢你!Caping TrueFalse来自Python。我什至不知道你可以这样写if
Michelfrancis Bustillos

1
还有更多的缩写:ideone.com/Dsbs8W和golfed ideone.com/HAzJ5V(<s> 255 </ s> 252个字符)。将C ++ 14用于foreach循环。
Qwertiy '16

1

待定Mathcad

在此处输入图片说明

在Mathcad中,0(标量)== false。

(等效)字节计数为TBD,直到同意计数方法为止。使用一个字节=运算符/符号键盘等效项,大约52个字节。


1

Mathematica 55 50 61 58字节

感谢MartinBüttner,节省了3个字节。

我之前的尝试并未通过所有测试用例。我需要添加Union以避免在列表中按顺序输入的重复。

Join@Union@Cases[NestList[RotateRight,#,Length@#],Sort@#]&

测验

Join@Union@Cases[NestList[RotateRight,#,Length@#],Sort@#]&/@
{{1},{5,0,5},{3,2,1},{0,9,3},{1,2,3,4},{4,1,2,3},{0,2,0,2},{5,3,9,2,6,7},
{0,0,0,0,0,0,0},{75,230,30,42,50},{255,255,200,200,203}}

{{1},{0,5,5},{},{},{1,2,3,4},{1,2,3,4},{},{},{0,0, 0,0,0,0,0},{30,42,50,75,230},{200,200,203,255,255}}


说明

将输入列表从1右旋转到n次,其中n是输入列表的长度。如果排序后的输入列表在输出循环列表中,则将其返回;否则,返回它。否则返回一个空列表。


@MartinBüttner,您的建议在某些测试用例中失败了,尤其是#3、4、7、8。
DavidC 2016年

@DavidC啊,该死,你是对的,我把@@和的行为混在一起了/@Join@@应该比现在更短Flatten@
Martin Ender

1

PHP,98字节

输出一个1if如果可漂移排序,否则不输出

$a=$argv[1];$b=$a;sort($a);foreach($a as $v){echo($a===$b?1:'');array_unshift($b, array_pop($b));}
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.