ポインタージャンプ


21

配列内のある場所を指すポインターを持つ長さ配列がとします。「ポインタージャンプ」のプロセスは、すべてのポインターを、ポインターが指す場所に設定します。psn

このチャレンジのために、ポインターは配列の要素の(ゼロベースの)インデックスです。これは、配列のすべての要素が以上未満であることをます。この表記を使用すると、プロセスは次のように定式化できます。0n

for i = 0..(n-1) {
  ps[i] = ps[ps[i]]
}

これは、(このチャレンジのために)ポインタが順番にインプレースで更新されることを意味します(つまり、インデックスが最初に低い)。

例、みましょう。ps = [2,1,4,1,3,2]

i = 0:the element at position ps[0] = 2 points to 4ps = [4,1,4,1,3,2]i = 1:the element at position ps[1] = 1 points to 1ps = [4,1,4,1,3,2]i = 2:the element at position ps[2] = 4 points to 3ps = [4,1,3,1,3,2]i = 3:the element at position ps[3] = 1 points to 1ps = [4,1,3,1,3,2]i = 4:the element at position ps[4] = 3 points to 1ps = [4,1,3,1,1,2]i = 5:the element at position ps[5] = 2 points to 3ps = [4,1,3,1,1,3]

そのため、「ポインタージャンプ」を1回繰り返した後、配列を取得し。[4,1,3,1,1,3]

チャレンジ

インデックスのある配列が与えられると、配列が変化しなくなるまで、上記のポインタのジャンプを繰り返して得られた配列を出力します。

ルール

あなたのプログラム/関数は、同じタイプ、リスト/ベクトル/配列などを受け取り、返し/出力します。

  • 空でないことが保証され、
  • エントリのみが含まれることが保証されます。0p<n

バリエーション:選択できます

  • 1ベースのインデックス作成を使用する、または
  • 実際のポインターを使用し、

ただし、これを提出する際に言及する必要があります。

テストケース

[0]  [0]
[1,0]  [0,0]
[1,2,3,4,0]  [2,2,2,2,2]
[0,1,1,1,0,3]  [0,1,1,1,0,1]
[4,1,3,0,3,2]  [3,1,3,3,3,3]
[5,1,2,0,4,5,6]  [5,1,2,5,4,5,6]
[9,9,9,2,5,4,4,5,8,1,0,0]  [1,1,1,1,4,4,4,4,8,1,1,1]


n追加の入力として長さを取ることはできますか?
ケビンクルーッセン

2
@KevinCruijssen、このメタディスカッションを参照してください。
シャギー

エントリを順番に更新する必要があるのは残念です。同時に更新できる場合、Mathematicaには21文字のソリューションがあり#[[#]]&~FixedPoint~#&ます。
グレッグマーティン

回答:






5

Swift68 53バイト

{a in for _ in a{var i=0;a.forEach{a[i]=a[$0];i+=1}}}

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

-15 BMOに感謝


2
PPCGへようこそ!私はSwiftを知りませんが、codegolf.SEでは、デフォルトでは型付きラムダ関数を受け入れます。したがって、これは53バイトになります(カウントする必要はありませんf=)。ここでの滞在をお楽しみください!
ბიმო

私の回答を更新するのに使用していた歓迎とアドバイスをありがとう。
ショーン

短くするmap代わりにforEachを使ってみてはどうですか?
ジェヨンは



4

Japt、15 13 7バイト

元の入力配列を変更します。

££hYXgU

試してみてください(追加のバイトは変更された入力をコンソールに書き込むことです)

££hYXgU
£           :Map
 £          :  Map each X at index Y
  hY        :    Replace the element at index Y
    XgU     :    With the element at index X

4

Java 8、105 54バイト

a->{for(int l=a.length,i=0;i<l*l;)a[i%l]=a[a[i++%l]];}

バイトを節約するために新しい配列を返す代わりに、入力配列を変更します。

length2

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

説明:

a->{                // Method with integer-array parameter and no return-type
  int l=a.length,   //  Length of the input-array
  i=0;i<l*l;)       //  Loop `i` in the range [0, length squared):
    a[i%l]=         //   Set the (`i` modulo-length)'th item in the array to:
      a[            //    The `p`'th value of the input-array,
        a[i++%l]];} //    where `p` is the (`i` modulo-length)'th value of the array

3

Japt、17バイト


®
£hYUgX
eV ?U:ß

すべてのテストケースを試す

これは短くする必要があるように感じますが、残念ながら私の最初の考えはUmgU機能しません。各ステップで変更するのではなく、それぞれgがオリジナルにアクセスするからUです。さまざまなコンポーネントを適切に保持するには、数バイトのコストもかかります。

説明:

           #Blank line preserves input in U long enough for the next line

®          #Copy U into V to preserve its original value

£hY        #Modify U in-place by replacing each element X with...
   UgX     #The value from the current U at the index X

eV ?U      #If the modified U is identical to the copy V, output it
     :ß    #Otherwise start again with the modified U as the new input




2

R60 58バイト

ルールを読んでくれた@digEmAllに感謝-2バイト。

function(x,n=sum(x|1)){for(i in rep(1:n,n))x[i]=x[x[i]];x}

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

1インデックス付き。

n 入力配列の長さです。

rep(1:n,n)1:n n時間を複製します(例n=3 => 1,2,3,1,2,3,1,2,3

配列n時間をループします。確かに、実際にはn-1回目の終わりまでに定常状態が達成されると思います。証拠は読者に任されています。


1
私はあなたが削除することができると思う+1と、単純に1ベースの入力、ポストの状態を取る:あなたは1ベースのインデックスを使用することもできます
digEmAll

-4 scan()入力用に切り替えて。私のscan()ソリューションは次善の策だといつも思っているので、より短い方法xn一緒に割り当ててn=length(x<-scan());for(i in rep(1:n,n))x[i]=x[x[i]];x ください
CriminallyVulgar



2

Clojure、136バイト

(defn j[a](let[f(fn[a](loop[i 0 a a](if(= i(count a))a(recur(inc i)(assoc a i(a(a i)))))))](loop[p nil a a](if(= p a)a(recur a(f a))))))

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


こんにちは、PPCGへようこそ。ソリューションを簡単に検証できるように、オンライン通訳者へのリンクを提供することは可能でしょうか?さらに、なることloop [はできませんloop[か?
ジョナサンフレッチ

1
最新の編集でテストの失敗修正する必要があります。ご不便をおかけして申し訳ありません。
イーサンマッキュー



1

、16バイト

FθFLθ§≔θκ§θ§θκIθ

オンラインでお試しください!リンクは、コードの詳細バージョンです。悲しいことに、すべての通常のマッピング関数は配列のコピーでのみ動作し、結果として、要素をジャンプするのではなく単に並べ替えるだけなので、コードはすべて手動で行う必要があります。説明:

Fθ

要素ごとに内側のループを1回繰り返します。これにより、結果が安定することが保証されます。

FLθ

配列インデックスをループします。

§≔θκ§θ§θκ

現在のインデックスで配列要素を取得し、それを使用して配列にインデックスを付け、現在の要素をその値に置き換えます。

Iθ

要素を文字列にキャストし、それぞれを独自の行に暗黙的に印刷します。


1

F#、74 73バイト

fun(c:'a[])->let l=c.Length in(for i in 0..l*l do c.[i%l]<-c.[c.[i%l]]);c

特にない。他の回答で見られるモジュラスのアイデアを使用します。


1

K、27バイト

{{@[x;y;:;x x y]}/[x;!#x]}/
  • {..}/ argにラムダ{..}を適用します(収束まで)

  • 内側ラムダ:

    • {..}/[x;y]x(反復ごとに更新される)およびyの項目(yは値のリストであり、各反復で項目を使用する)にラムダを繰り返し適用します。この場合、arg yは!#x(xをカウントするまで、つまり配列のインデックス)

    • @[x;y;:;x x y] 配列xを修正する(インデックスyでx [x [y]]を割り当てる)


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