逆挿入ソート


19

目的

挿入ソートの動きから、元のスクランブルリストを生成しますするします。元のリストからすべての数字を持っているだろう0N-1(包括的)N入力の大きさです。

入力

リストをソートするために必要な移動を含むリスト。各値は、元の(スクランブルされた)番号によって正しい位置に移動するスロットの量を表します。このプロセスは左から右であることに注意してください。入力リストの
(0からインデックス付けされた)位置の値は、両端の値を含みます。 無効な入力を処理する必要はありません。この場合、どのような動作も許容されます(クラッシュ、無限ループなど)。i0i

出力

スクランブルリスト

動きを生成するためのステップバイステップ

Scrambled List | Moves to sort
[4,0,2,1,3,5]  | [0, , , , , ] #4 stay in place
[4,0,2,1,3,5]  | [0,1, , , , ] #0 is moved 1 slot to the left
[0,4,2,1,3,5]  | [0,1,1, , , ] #2 is moved 1 slot
[0,2,4,1,3,5]  | [0,1,1,2, , ] #1 is moved 2 slot
[0,1,2,4,3,5]  | [0,1,1,2,1, ] #3 is moved 1 slot
[0,1,2,3,4,5]  | [0,1,1,2,1,0] #5 is in the right place already
[0,1,2,3,4,5]

したがって、入力のために[0,1,1,2,1,0]プログラムは出力する必要があります[4,0,2,1,3,5]
移動は(最終)ソート済みリストの位置ではなく、ソート済みセグメント(太字部分)の位置にあることに注意してください

テストケース

[0,0,0] -> [0,1,2]
[0,1,0,1] -> [1,0,3,2]
[0,0,0,0,0,5] -> [1,2,3,4,5,0]
[0,1,2,3] -> [3,2,1,0]
[0,1,1,1] -> [3,0,1,2]
[0,1,1,2,1,0] -> [4,0,2,1,3,5]

勝ち

これはなので、最短の答えが勝ちです。

code-golf  array-manipulation  code-golf  code-golf  animation  code-golf  restricted-source  code-golf  java  code-golf  decision-problem  graph-theory  code-golf  conversion  electrical-engineering  code-golf  ascii-art  code-golf  string  substitution  code-golf  math  code-golf  string  set-theory  code-golf  code-golf  compile-time  code-golf  kolmogorov-complexity  binary  code-golf  sequence  cops-and-robbers  code-golf  subsequence  card-games  code-golf  sequence  primes  code-golf  code-golf  number  graphical-output  music  code-golf  ascii-art  code-golf  string  lambda-calculus  code-golf  string  code-generation  code-golf  unicode  code-golf  math  combinatorics  code-golf  balanced-string  code-golf  sequence  cops-and-robbers  code-golf  sequence  cops-and-robbers  code-challenge  fastest-code  chess  code-golf  math  graphical-output  code-golf  string  hello-world  animation  code-golf  number  arithmetic  code-golf  integer  code-golf  code-golf  combinatorics  code-golf  kolmogorov-complexity  graphical-output  code-golf  string  code-golf  code-golf  game  code-golf  math  combinatorics  code-golf  ascii-art  popularity-contest  random  code-golf  arithmetic  number-theory  integer  code-golf  tips  underload  code-golf  math  sequence  primes  code-golf  math  path-finding  code-golf  ascii-art  primes  code-golf  kolmogorov-complexity  alphabet 

1
プログラムは入力としてリストの長さも取得できますか?
mbomb007

@ mbomb007いや。
ロッド

代わりに(n-1)ステップを使用できますか?最初のものは、常にゼロであるため、不要です。
GB

長い出力が正しいよう@GB必ず、あなたは任意のアルゴリズムを使用することができます
ロッド

回答:


14

ゼリー、12バイト

L!_UÆ¡$œ?J’U

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

説明

基本的に、2つのリスト(入力と出力)は整数のエンコードとして見ることができます。入力は階乗ベースで整数をエンコードし、出力は順列として整数をエンコードします。幸いなことに、Jellyにはこれらの両方のエンコーディングにすでに非常に近い組み込み関数があるため、整数に変換してから他のエンコーディングに戻すための小さなコードを書くだけです。

L!_UÆ¡$œ?J’U
   U           Reverse {the input}
    Æ¡         and convert from base factorial to integer;
  _   $        subtract that from
L!             the factorial of the length of {the input};
       œ?      then take the nth permutation of
         J     [1,2,...,l], where l is the length of {the input},
          ’    subtract 1 from every elevent,
           U   and reverse it

基本階乗の場合、リストの最初の要素は0でなければならず、2番目の要素は0または1になり、3番目の要素は0/1/2になります。したがって、基本変換のためにその要素を通常の書き込み順序にするには、入力を逆にする必要があります。

さらに、階乗変換と置換変換の相対的な順序を、挿入ソートが使用する操作と一致させるために、2つの調整を行う必要があります。順列の順序を逆にすることと、出力リストの順序を逆にすることです。出力リストの反転は簡単で、必要なのはUで、プログラムの最後でです。順列の順序を逆にするには、入力の長さの階乗から減算します(基本階乗は0から(長さ!-1)の範囲の数値を生成するため、これは機能しますが、順列はJellyによって1から長さの番号が付けられます! 、因数分解から置換インデックスを減算するときに通常得られるオフバイワンを相殺する暗黙のオフバイワンを生成します)。

Jelly、9バイト、@ JonathanAllanとのコラボレーション

UÆ¡Nœ?J’U

このバージョンのプログラムは非常に似ていますが、順列の順序を逆にする異なる方法を使用しています。単に入力を否定するだけNで十分ですœ?、順序を逆に扱うです。それ以外は、以前のプログラムと同じように機能します。

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


4
O_Oこれどんな魔術ですか?
DLosc

いいですね-私Æ¡と私のœ?原子がこれでうまくいくことを知っていました(私はすでに以前にこの挑戦のためにそれらを使用しようと試みていました-私はとても近く、ちょうどL!そこに必要でした)。
ジョナサンアラン

優れたコード!
グレッグマーティン

1
実際、9バイトでそれを行うことができます。これは、(Jellyリストを使用しているかのように)モジュール式に動作するようUÆ¡Nœ?L’Uに実装œ?(および類似)しているためです。N負の値を持つでちょうどインデックス。注:に変更JしましたL-これは、数値を指定すると、とにかく内部の範囲が作成されるためです。
ジョナサンアラン

6

Mathematica、92バイト

Permute[Range[l=Length@#]-1,(c=Cycles@{#}&)@{}©##&@@c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]&

入力として非負の整数のリストを取り、非負の整数のリストを返す純粋な関数。上記のコードにはが含まれていますが©、これは正しくありません。これは、3バイトのシンボルU + F3DEのプレースホルダーです。

c=Cycles@{#}&整数のリストをCycles順列を表すオブジェクトに変換する関数を定義します。たとえば、c[{3,4}]リストの転置スワッピング要素3と4です。c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]入力リストを取得し、挿入ソートを元に戻すために必要な順列を生成します。次にc@{}©##&@@、恒等順列から始めて、これらすべての順列を一緒に構成しますc@{}。最後に、Permute[Range[l=Length@#]-1,...]この順列を適切な長さの0インデックス付きリストに適用します。


1
何が組み込まれていませんか?!確かに...
ジョナサン・アラン

3
@{#}&)@{}©##&@@怖いですね。
イッツィー

6

Python 2、79 68バイト

10バイトを節約してくれたKrazorに感謝

1バイトを保存してくれたTuukkaXに感謝

a=input();b=range(len(a));print[b.pop(j-a[j])for j in b[::-1]][::-1]

逆の動きを生成することにより動作します


2
その66を作ります!方法:a=input();b=range(len(a));print[b.pop(j-a[j]) for j in b[::-1]][::-1]。内包表記をリストします!
FMaz

1
@Krazor前forに削除できるスペースがあるので、その65を作成します:D
Yytsi

@Krazorはリストの内包表記がうまくいかなかったことが判明しましたが、b [::-1]を使用するというアイデアが気に入りました。
数学中毒

とんでもない?私はモバイルでコメントしました、多分私は何かをタイプミスしました。どの部分が機能しないのですか?私にとっては、正しく解釈され、すべてのテストケースが満たされました。
FMaz

@Krazorおっと、あなたは正しい。テスト中にタイプミスしたのは私です。
数学中毒

5

JavaScript(ES6)、69 65 63バイト

a=>a.reverse(b=[...a.keys()]).map(o=>+b.splice(~o,1)).reverse()

迷惑なことに、入力と出力の両方の順序が間違っています。編集:@Arnauldのおかげで4バイトを保存しました。@ETHproductionsのおかげで2バイト節約されました。


私はまだより良い方法を見つけようとしていましたが、あなたははるかに高速でした。良いですね!
アーナウド

1
必要iありませんよね?
アーナウド

@Arnauldどうやらそうではありません。私は、Pythonの答えを理解しようとすることで始めた、と私はちょうどそれが実際に使用していないことに気付きましたi...
ニール

1
Easy -2:o=>+b.splice(~o,1)
ETHproductions

3

JavaScript(ES6)、73 71バイト

ETHproductionsのおかげで2バイト節約

m=>(a=m.map((_,i)=>j=i)).map(_=>a.splice(j,0,+a.splice(j-m[j--],1)))&&a

テストケース


長さと範囲を同時に取得する良い方法。私は提案するつもりでしたがa=m.map(_=>j++,j=0)、それは同じ長さで、あなたはすでにそれを試したことがあると確信しています。
ETHproductions

@ETHproductionsそのとおりです。私も試してみました。:ja.lengtha.length-1a.splice(--j,0,a.splice(j-m[j],1)[0])
-Arnauld

ふむ、私もそのことを考えて、それは同じ長さなので、私はそれが言及する価値だったとは思いませんでした
ETHproductions

1
Easy -2:+a.splice(j-m[j--],1)
ETHproductions

2

Haskell、85バイト

f x|n<-length x-1=reverse x#[n,n-1..0]
(n:r)#l=r#(take n l++drop(n+1)l)++[l!!n]
x#l=x

オンラインでお試しください!使用例:f [0,1,1,2,1,0]yields [4,0,2,1,3,5]

f x#listをx逆にしてlistを指定して関数を呼び出します[length x - 1, length x - 2, ... , 0](n:r)#lは、nthの要素を再帰的に取り出して逆挿入ソートを実行しますl。ここでl!!nnthの要素をtake n l++drop(n+1)l生成lし、nthの要素を削除したリストを生成します。


ハスケル、とても美しい。
FMaz

1

perl、61バイト

@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p

出力は配列@oになります。コマンドライン引数として入力配列を使用した例:

perl -le'@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p;print@o' 0 1 1 2 1 0
402135

1

ルビー、49バイト

->l{(w=l.size).times{l.insert(l.shift+w-=1,w)};l}

リスト内の所定の位置で、最大数から始まる「逆挿入」を実行します。

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