フロップする方法を教えてください


29

コンピューターサイエンティストとして、おそらくpoppushの基本的なリスト操作に慣れているでしょう。これらは、要素のリストを変更する簡単な操作です。しかし、操作フロップについて聞いたことがありますか?(フリップフロップのように)?とても簡単です。番号nを指定すると、リストの最初のn要素を逆にします。以下に例を示します。

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a.flop(4)
[4, 3, 2, 1, 5, 6, 7, 8, 9, 10]

フロップ操作のクールな点は、ソートなど、リストに対してクールなことを実行できることです。フロップでも同様のことを行います。

整数のリストを指定すると、「Neighbor it」。つまり、重複する要素がすべて連続して表示されるように並べ替えます。

これはフロップで行えます!たとえば、次のリストをご覧ください。

>>> a = [3, 2, 1, 4, 3, 3, 2]
>>> a.flop(4)
[4, 1, 2, 3, 3, 3, 2]
>>> a.flop(3)
[2, 1, 4, 3, 3, 3, 2]
>>> a.flop(6)
[3, 3, 3, 4, 1, 2, 2]

これは、今日の課題の定義につながります。

整数のリストが与えられると、リストが隣接する結果となるフロップのセットを出力します。

例として最後のリストを使用して、次を出力する必要があります。

4
3
6

リストを4、3、6の順にフロップすると、隣接リストになります。リストに隣接するフロップの最短リストを印刷する必要はないことに注意してください。印刷した場合:

4
4
4
3
1
1
6
2
2

代わりに、これはまだ有効な出力です。ただし、リストの長さを超える数値を出力することはできません。これは、listのa = [1, 2, 3]場合、呼び出しa.flop(4)は無意味だからです。

ここではいくつかの例を示します。

#Input:
[2, 6, 0, 3, 1, 5, 5, 0, 5, 1]

#Output
[3, 7, 8, 6, 9]


#Input
[1, 2]

#Output
<any list of integers under 3, including an empty list>


#Input
[2, 6, 0, 2, 1, 4, 5, 1, 3, 2, 1, 5, 6, 4, 4, 1, 4, 6, 6, 0]

#Output
[3, 19, 17, 7, 2, 4, 11, 15, 2, 7, 13, 4, 14, 2]


#Input
[1, 1, 1, 1, 2, 2, 2, -1, 4]

#Output
[]


#Input
[4, 4, 8, 8, 15, 16, 16, 23, 23, 42, 42, 15]

#Output
[12, 7]

これらの各例では、与えられた出力は有効な出力の1つにすぎないことに注意してください。前に言ったように、与えられたリストに隣接するフロップのセットはすべて有効な出力です。このpythonスクリプトを使用し、特定のフロップリストがリストに正しく隣接しているかどうかを確認できます。

合理的な形式で入出力を行うことができます。たとえば、関数の引数/戻り値、STDIN / STDOUT、ファイルの読み取り/書き込みなどはすべて有効です。いつものように、これはなので、できるだけ短いプログラムを作成し、楽しんでください!:)


3
fl(oating point)op(eration)として聞いた。
周jun順

3
@WeijunZhouこれは、ハードウェアの一部で実行される操作をカウントするための計算速度の尺度です。en.wikipedia.org/wiki/FLOPS
iPhoenix

3
提出は決定論的である必要がありますか、または配列がグループ化されるまで擬似ランダムにフロップできますか?
デニス

3
出力にゼロフロップを表示できますか?
ライコニ

4
関連。NBその質問への答えはこれに対する答えになりますが、ソートされることは「隣人」であるよりも強い条件であるため、それらをアウトゴルフすることが可能かもしれないので、これは重複ではないかもしれませんこれまでのところ、答えは勇気づけられない)。
ピーターテイラー

回答:


7

Haskell98 71バイト

h.r
h(x:s)|(a,b)<-span(/=x)s=l b:l s:h(b++r a)
h e=e
r=reverse
l=length

オンラインでお試しください!

説明

長さのリストの場合、nこのメソッドは2*nフロップを作成します。リストの最後の要素を見て、リスト内の同じ要素を前に探し、それを最後から2番目の位置にフリップすることで機能します。次に、最後の要素が削除されたリストが再帰的に「隣接」されます。

リストで[1,2,3,1,2]は、アルゴリズムは次のように機能します。

[1,2,3,1,2]  flip longest prefix that ends in 2: flop 2
[2,1,3,1,2]  bring first element to second to last position: flop n-1 = flop 4
[1,3,1,2,2]  recursively work on n-1 list
[1,3,1,2]    there is no other 2: flop 0
[1,3,1,2]    flop n-1 = flop 3
[1,3,1,2]    recurse
[1,3,1]      flop 1
[1,3,1]      flop 2
[3,1,1]      recurse
[3,1]        flop 0
[3,1]        flop 1
 ...

これにより、フロップ[2,4,0,3,1,2,0,1,0,0]と隣接リストが生成され[3,1,1,2,2]ます。


6

Wolfram言語(Mathematica)、71バイト

If[(n=Tr[1^#])<1,{},{i=Last@Ordering@#,n,n-1,i-1}~Join~#0[#~Drop~{i}]]&

オンラインでお試しください!

使い方

length nの配列を指定する4nと、配列を昇順でソートする一連のフロップを出力します。特に、重複する要素を隣り合わせに配置します。

配列を並べ替えるには、その最大要素を最後に移動してn-1から、配列の最初の要素を並べ替えます。フロップ操作の実装を回避するために、他の要素を妨げない方法で最大の要素を最後に移動します。

{3, 2, 1, 5, 3, 3, 2}    starting array, with largest element in position 4
{5, 1, 2, 3, 3, 3, 2}    flop 4 to put the largest element at the beginning
{2, 3, 3, 3, 2, 1, 5}    flop 7 to put the largest element at the end
{1, 2, 3, 3, 3, 2, 5}    flop 6 (7-1) to reverse the effect of flop 7 on other elements
{3, 2, 1, 3, 3, 2, 5}    flop 3 (4-1) to reverse the effect of flop 4 on other elements

一般に、最大の要素が位置iにある場合、それを最後に移動するフロップのシーケンスはi, n, n-1, i-1です。


で最大の要素を最後に移動できi, nます。どうしてn-1, i-1安定したソートの必要はありません。
ピーターテイラー

@PeterTaylor答えが実際にフロップを実行するのではなく、毎回最大の要素を削除し、その操作に相当するものをフロップに関して出力します。
ニール


3

ゼリー19 17バイト

ỤỤạ‘Ḣ
ỤÇÐƤĖµUż’ṚF

リストをソートします。

オンラインでお試しください!


モジュロỤŒ¿’Æ!‘ṚĖµUż’ṚFなので、逆ソートと思います。Œ¿L!
ジョナサンアラン

おそらく、私のコードは、同様にいくつかのあいまいなエッジケースのために失敗することを意味し、最後のテストケースのための仕事をしません何らかの理由で、...
デニス

そして、それは確かに入力に対して失敗します[4, 3, 2, 1, 3]。残念。
デニス

ああ、ブー; 残念です。
ジョナサンアラン

Ụ>Ṫ$ƤSạỤĖµUż’ṚFヘルパーリンクを置き換えることで2バイトを節約します。
マイル


1

JavaScript、150バイト

(a,f=n=>(a=[...a.slice(0, n).reverse(),...a.slice(n)],n),l=a.length,i=0)=>a.reduce(c=>[...c,f(a.indexOf(Math.max(...a.slice(0, l-i)))+1),f(l-i++)],[])

オンラインでお試しください!

JavaScript、151バイト

a=>{f=n=>(a=[...a.slice(0,n).reverse(),...a.slice(n)],n),r=[];for(i=a.length+1;--i>0;)r.push(f(a.indexOf(Math.max(...a.slice(0, i)))+1),f(i));return r}

オンラインでお試しください!

どちらも、基本的には、最大数を最初に反転させてから後ろに反転させ、残りの配列でこれを繰り返すことにより、配列をソートします。1つ目はreduceを使用し、2つ目はforループを使用します。

ゴルフをしていない:

array => {
  let flop = n => {
    array = [...array.slice(0, n).reverse(), ...array.slice(n)]; 
    return n;
  }
  let flops = [];
  for (let i = array.length + 1; --i > 0;) 
  {
    let maxIndex = array.indexOf(Math.max(...array.slice(0, i)));
    flops.push(flop(maxIndex + 1), flop(i));
  }
  return flops;
}

0

Perl 5.10(以降)、66バイト

含ま+3のために5.10を無料考えられているPerlのレベルに言語をもたらすために-nuse 5.10.0

#!/usr/bin/perl -n
use 5.10.0;
$'>=$&or$.=s/(\S+) \G(\S+)/$2 $1/*say"$. 2 $."while$.++,/\S+ /g

入力をSTDINの1行として実行します。

flop.pl <<< "1 8 3 -5 6"

繰り返し反転を見つけてリストをソートします。先頭にフロップし、次に反転をフロップし、すべてを元の位置にフロップします。

この1つでPythonと同じ球場に入るのは驚くほど大変でした:-)


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.