二重にリンクされたデータを解きます


12

二重リンクリストは、各ノードがリスト内と次のvalue両方への「リンク」と同様に持つデータ構造です。たとえば、値が12、99、および37の次のノードを考えます。previousnodes

ここで、値12および99のnextノードは、値99および37のそれぞれのノードを指します。値が37のnextノードは、リスト内の最後のノードであるため、ポインターを持ちません。同様に、値99および37のpreviousノードはそれぞれのノード12および99を指しますが、12にはありませんprevious指しますが、リストの最初のノードであるためポインター。

セットアップ

実際には、ノードの「リンク」は、メモリ内の前および次のノードの場所へのポインターとして実装されます。私たちの目的では、「メモリ」はノードの配列であり、ノードの場所は配列内のインデックスになります。ノードは、形式の3タプルと考えることができます( prev value next )。上記の例は、次のようになります。

ただし、代わりに次のようになります。

任意のノードから開始して、previousリンク(赤い矢印の原点として表示)をたどってその前のノードに移動し、nextリンク(緑の矢印)を使用して後続のノードを検索し、すべてのノードの値を順番に取得できます。[12, 99, 37]

上記の最初の図は、配列でとして表すことができます[[null, 12, 1], [0, 99, 2], [1, 37, null]]。次に、2番目はになります[[2, 99, 1], [0, 37, null], [null, 12, 0]]

チャレンジ

ノードの配列とノードのインデックスを入力として受け取り、同じ二重リンクリスト内のノードの値をリスト順に返すプログラムを作成します。

合併症

「メモリ」には、常に1つのリストのノードが含まれているとは限りません。複数のリストが含まれる場合があります。

上記の配列には、利便性のために色分けされた3つの二重リンクリストが含まれています。

  1. インデックスのノードは71014312(のみ示すnext煩雑さを軽減するためのリンク。クリックすると拡大します):

    この配列とこれらのインデックスのいずれかが与えられると、プログラムは値を順番に返す必要があります[0, 1, 1, 2, 3, 5, 8]

  2. インデックスのノード9

    インデックスを指定する9と、プログラムが返され[99]ます。

  3. インデックスのノード118062

    これらのインデックスのいずれかを指定すると、返されるはずです [2, 3, 5, 7, 11]ます。

ルール

入力

あなたのプログラムは入力として受け取ります:

  1. 𝒏ノードのリスト(上記の3タプル)、ここで1≤𝒏≤1,000、任意の便利な形式(配列の配列、長さ3𝒏の整数の「フラット」配列など)

    :3タプル要素は、任意の順序であってもよく( prev value next )( next prev value )各ノードについて、等、prevnextなりますnull(または別の便利な値、例えば-1)、二重にリンクされたリストの最初または最後のノード、または有効なインデックスを示します便利なように、0ベースまたは1ベースのリスト。value符号付き32ビット整数または言語がサポートする最大の整数型のいずれか小さい方になります。

  2. リスト内のノードのインデックス𝒑(1)。指定されたノードは、二重リンクリストの最初のノード、最後のノード、中間ノード、または唯一のノードです。

入力リスト(1)には病理学的データ(たとえば、サイクル、他の複数のノードが指すノードなど)が含まれる場合がありますが、入力インデックス(2)は常に、単一の整形式出力が可能なノードを指します推論された。

出力

プログラムは、インデックスatのノードがメンバーになっている二重リンクリストのノードの値をリスト順に出力する必要があります。出力は任意の便利な形式にすることができますが、そのデータにはノードのみが含まれている必要がありますvalue

勝ち

これはです。バイト単位の最短回答が優先されます。標準の抜け穴が適用されます。

テストケース

以下に、各テストケースの形式を示します。

X)
prev value next, prev value next, ...
index
value value value ...

...ここでX、テストケースを識別するための文字、2行目は入力リスト、3行目は0から始まる入力インデックス、4行目は出力です。

A) null 12 1, 0 99 2, 1 37 null
   1
   12 99 37

B) 2 99 1, 0 37 null, null 12 0
   1
   12 99 37

C) 8 5 6, 10 1 4, 6 11 null, 4 3 12, 1 2 3, 12 8 null, 0 7 2, null 0 10, 11 3 0, null 99 null, 7 1 1, null 2 8, 3 5 5
   4
   0 1 1 2 3 5 8

D) 8 5 6, 10 1 4, 6 11 null, 4 3 12, 1 2 3, 12 8 null, 0 7 2, null 0 10, 11 3 0, null 99 null, 7 1 1, null 2 8, 3 5 5
   0
   2 3 5 7 11

E) 8 5 6, 10 1 4, 6 11 null, 4 3 12, 1 2 3, 12 8 null, 0 7 2, null 0 10, 11 3 0, null 99 null, 7 1 1, null 2 8, 3 5 5
   9
   99

F) 13 80 18, 18 71 null, 5 10 19, 12 1 8, 19 21 null, 31 6 2, 17 5 26, 26 0 30, 3 -1 25, null 1 23, 27 6 17, 14 1 24, 28 -1 3, null 80 0, 20 4 11, 33 6 29, 24 9 33, 10 7 6, 0 67 1, 2 15 4, 32 1 14, null 1 31, 29 3 null, 9 -1 28, 11 5 16, 8 1 null, 6 3 7, null 8 10, 23 1 12, 15 5 22, 7 9 null, 21 3 5, null 3 20, 16 2 15
   18
   80 80 67 71

G) 13 80 18, 18 71 null, 5 10 19, 12 1 8, 19 21 null, 31 6 2, 17 5 26, 26 0 30, 3 -1 25, null 1 23, 27 6 17, 14 1 24, 28 -1 3, null 80 0, 20 4 11, 33 6 29, 24 9 33, 10 7 6, 0 67 1, 2 15 4, 32 1 14, null 1 31, 29 3 null, 9 -1 28, 11 5 16, 8 1 null, 6 3 7, null 8 10, 23 1 12, 15 5 22, 7 9 null, 21 3 5, null 3 20, 16 2 15
   8
   1 -1 1 -1 1 -1 1

H) 13 80 18, 18 71 null, 5 10 19, 12 1 8, 19 21 null, 31 6 2, 17 5 26, 26 0 30, 3 -1 25, null 1 23, 27 6 17, 14 1 24, 28 -1 3, null 80 0, 20 4 11, 33 6 29, 24 9 33, 10 7 6, 0 67 1, 2 15 4, 32 1 14, null 1 31, 29 3 null, 9 -1 28, 11 5 16, 8 1 null, 6 3 7, null 8 10, 23 1 12, 15 5 22, 7 9 null, 21 3 5, null 3 20, 16 2 15
   4
   1 3 6 10 15 21

I) 13 80 18, 18 71 null, 5 10 19, 12 1 8, 19 21 null, 31 6 2, 17 5 26, 26 0 30, 3 -1 25, null 1 23, 27 6 17, 14 1 24, 28 -1 3, null 80 0, 20 4 11, 33 6 29, 24 9 33, 10 7 6, 0 67 1, 2 15 4, 32 1 14, null 1 31, 29 3 null, 9 -1 28, 11 5 16, 8 1 null, 6 3 7, null 8 10, 23 1 12, 15 5 22, 7 9 null, 21 3 5, null 3 20, 16 2 15
   14
   3 1 4 1 5 9 2 6 5 3

J) 13 80 18, 18 71 null, 5 10 19, 12 1 8, 19 21 null, 31 6 2, 17 5 26, 26 0 30, 3 -1 25, null 1 23, 27 6 17, 14 1 24, 28 -1 3, null 80 0, 20 4 11, 33 6 29, 24 9 33, 10 7 6, 0 67 1, 2 15 4, 32 1 14, null 1 31, 29 3 null, 9 -1 28, 11 5 16, 8 1 null, 6 3 7, null 8 10, 23 1 12, 15 5 22, 7 9 null, 21 3 5, null 3 20, 16 2 15
   17
   8 6 7 5 3 0 9

K) 4 11 0, null 22 3, null 33 3, 1 44 4, 3 55 null, 7 66 7, 6 77 6
   3
   22 44 55

L) null -123 null
   0
   -123

サンドボックスリンク:codegolf.meta.stackexchange.com/a/14451/11261
ヨルダン


入力は3つの配列(順番にすべての先行ノード、1つの値、1つの後続ノードを含む)として許可されますか、それともタプルの概念から遠すぎますか?
-Sanchises

@Sanchisesすみません、私には遠すぎます。
ヨルダン

大丈夫です!私はそう思いましたが、別々の配列を使用して2バイトを削ることができるという私の答えに対するコメントよりも先になりたかったのです。
-Sanchises

回答:


1

05AB1E、25バイト

è[¬D0‹#Isè]\[`sˆD0‹#Isè]¯

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

説明

è[¬D0‹#Isè]\[`sˆD0‹#Isè]¯   # Arguments n, a
è                           # Get element at index n in a
 [¬D0‹#Isè]                 # Find the first element in the list
 [                          # While true, do
  ¬                         #   Head (get index of previous element)
   D0‹#                     #   Break if lower than 0
       Isè                  #   Get the element at that index
          ]                 # End loop
           \                # Delete top element of stack
            [`sˆD0‹#Isè]    # Iterate through list
            [               # While true, do
             `sˆ            #   Add value to global array and keep next index on stack
                D0‹#Isè     #   Same as above
                       ]    # End loop
                        ¯   # Push global array

3

Haskell79 65 59 55バイト

ブルートフォースのおかげで-6バイト。

x#i|let-1!d=[];i!d=i:x!!i!!d!d=[x!!i!!1|i<-last(i!0)!2]

として表される#整数のリストのリストを受け入れる関数を定義し、ノード値のリストを返します。null-1

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

説明

let-1!d=[];i!d=i:x!!i!!d!d

!nodeで始まるノードを反復処理し、iアクセスしたインデックスのリストを返す関数を定義します。d「タプル」のどのインデックスを次のノードのインデックスとして使用するかを指定する2番目の引数を受け入れます(d==2前方d==0に繰り返す、後方に繰り返す)。

(i!0)

指定されたインデックスから逆方向に反復し、訪問したインデックスを返します。

last(i!0)

リストの先頭にある最後にアクセスしたインデックスを取得します。

last(i!0)!2

リストの先頭から繰り返します。

[x!!i!!1|i<-last(i!0)!2]

訪問した各インデックスをノードの値に置き換えます。


あなたはほとんどx!!i!!1として書くことができますが、出力のi!1!!1ために壊れ-1ます。あなただけ表現するために、別のセンチネル値を選択した場合はnull(と言う、-9)、それは動作しますが、それは常にのために壊すよ、いくつかの非常に迷惑である入力、。
リン

3

Python 2、60バイト

l,n=input()
while~n:m=n;n=l[n][0]
while~m:p,v,m=l[m];print v

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

これは、Chas Brownの答えであり、これらのゴルフを除いたものです。

  • nを再利用して、割り当てを保存します
  • 最後の有効なnをmに保存して、
  • 3行目の課題の後にプリントを配置し、最終的なプリントを保存します
  • 負の値は正の値と同じくらい真実であるため、-〜nではなく〜nのみを使用し、2文字節約します。


2

MATL、39バイト

XHx`HwI3$)t]x6Mt`Hwl3$)tbhwt]x4L)Hw2I$)

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

私のOctaveの答えのほぼ直接的なポートですが、このバージョンは最初に終わりを見つけてから、1バイトを節約した逆方向ではなく、後ろに戻ります。

XHx           % Store array in H.
`HwI3$)t]     % Work to the end of the array
x6Mt          % Delete the end of array delimiter, and push the array end index twice
`Hwl3$)    t] % Work to the beginning of the array
       tbhw   % Append all indices found.
Hw2I$)        % Index into original array.

1

PHP、132バイト

<?list(,$x,$y)=$argv;parse_str($x);while(($q=$x[$y*3+1])>=0)$y=$q;do{$n[]=$x[$y*3+2];$y=$x[$y*3];}while($x[$y*3]);echo join(' ',$n);

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

入力は、クエリ文字列としたx[]=-1&x[]=1&x[]=1...順に、(フラットアレイ内のすべてのノード)nextprev次に、valueノードを終了するために使用して-1ノードごと。


1

パイソン281の 77バイト

a,n=input()
u=a[n][0]
while-~u:u,v,w=a[u]
while-~w:print v;u,v,w=a[w]
print v

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

編集:ミスターXcoderへの4バイトのThx ...

タプル[u、v、w]のリストを取得します。ここで、uとwは-1で、リンクされたリストセグメントの開始/終了を表します。


77バイトオンラインでお試しください!。ブール値はintのサブクラスであるため0、Falsy のみであるため、u>=0ゴルフにかけるu+1ことができ、これをさらに短縮し-~uて空白を削除できます。
ミスターXcoder

@氏。Xcoder-はい、まったくその通りです!
チャスブラウン

1

オクターブ81 78 76バイト

function o=f(a,n)while q=a(n,1)o=a(n=q,2);end
while n=a(n,3)o=[o a(n,2)];end

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

むしろ簡単なバージョン。説明は読者への課題として残されています。より楽しいバージョンを以下に示します:

オクターブ142 99 92バイト

@(a,n)[(p=@(b,c,z){q=a(z,2),@()[b(b,c,a(z,c)),q]}{2-~a(z,c)}())(p,1,n),p(p,3,n)(end-1:-1:1)]

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

ヨ、私はあなたが匿名関数が好きだと聞いた...

nx3最初の列が先行ノード、2番目の列が値、3番目の値が後続ノードの配列を受け取ります。すべてのノードインデックスは1から始まり、Octaveのデフォルトです。

% Create an anonymous function, taking an array a and first node n
@(a,n)
% Returns an array containing the predecessor and sucessor nodes
      [                                                                     ,                     ]
% Defines an recursive anonymous function (by supplying itself to the local namespace)
% which looks at the first column (c=1) or last column (c=3) of the input array to get the next nodes
       (p=@(p,c,z)                                                   )(p,1,n)
% Create a cell array, either containing the end node,
                    {q=a(z,2),                       
% ...or an array with all next  next nodes and the current node
% (note the use of an anonymous function taking no parameters to defer array access, in case of the last node)                
                              @()[p(p,c,a(z,c)),q]}
% depending whether the next node number is nonzero (followed by () to execute the deferred array access)
                                                    {2-~a(z,c)}()
% Do the same with c=3, reverse (function p builds the array right-to-left) and drop the current node to prevent a duplicate.                                                                             
                                                                             p(p,3,n)(end-1:-1:1)

1

Kotlin、85バイト

{g,S->generateSequence(generateSequence(S){g[it][0]}.last()){g[it][2]}.map{g[it][1]}}

美化

{g,S->
    generateSequence(generateSequence(S){g[it][0]}.last()){ g[it][2]}.map { g[it][1] }
}

テスト

typealias Node=Triple<Int?,Int?,Int?>
data class Test(val input: List<Node>, val start:Int, val result: List<Int>)
val TEST = listOf<Test>(
Test(
listOf(Node(null, 12, 1), Node(0, 99, 2), Node(1, 37, null)),
1,
listOf(12, 99, 37)
),
Test(listOf(
Node(2, 99, 1), Node(0, 37, null), Node(null, 12, 0)),
1,
listOf(12, 99, 37)
),
Test(
listOf(Node(8, 5, 6), Node(10, 1, 4), Node(6, 11, null), Node(4, 3, 12), Node(1, 2, 3), Node(12, 8, null), Node(0, 7, 2), Node(null, 0, 10), Node(11, 3, 0), Node(null, 99, null), Node(7, 1, 1), Node(null, 2, 8), Node(3, 5, 5)),
4,
listOf(0, 1, 1, 2, 3, 5, 8)
),
Test(
listOf(Node(8, 5, 6), Node(10, 1, 4), Node(6, 11, null), Node(4, 3, 12), Node(1, 2, 3), Node(12, 8, null), Node(0, 7, 2), Node(null, 0, 10), Node(11, 3, 0), Node(null, 99, null), Node(7, 1, 1), Node(null, 2, 8), Node(3, 5, 5)),
0,
listOf(2, 3, 5, 7, 11)
),
Test(
listOf(Node(8, 5, 6), Node(10, 1, 4), Node(6, 11, null), Node(4, 3, 12), Node(1, 2, 3), Node(12, 8, null), Node(0, 7, 2), Node(null, 0, 10), Node(11, 3, 0), Node(null, 99, null), Node(7, 1, 1), Node(null, 2, 8), Node(3, 5, 5)),
9,
listOf(99)
),
Test(
listOf(Node(13, 80, 18), Node(18, 71, null), Node(5, 10, 19), Node(12, 1, 8), Node(19, 21, null), Node(31, 6, 2), Node(17, 5, 26), Node(26, 0, 30), Node(3, -1, 25), Node(null, 1, 23), Node(27, 6, 17), Node(14, 1, 24), Node(28, -1, 3), Node(null, 80, 0), Node(20, 4, 11), Node(33, 6, 29), Node(24, 9, 33), Node(10, 7, 6), Node(0, 67, 1), Node(2, 15, 4), Node(32, 1, 14), Node(null, 1, 31), Node(29, 3, null), Node(9, -1, 28), Node(11, 5, 16), Node(8, 1, null), Node(6, 3, 7), Node(null, 8, 10), Node(23, 1, 12), Node(15, 5, 22), Node(7, 9, null), Node(21, 3, 5), Node(null, 3, 20), Node(16, 2, 15)),
18,
listOf(80, 80, 67, 71)
),
Test(
listOf(Node(13, 80, 18), Node(18, 71, null), Node(5, 10, 19), Node(12, 1, 8), Node(19, 21, null), Node(31, 6, 2), Node(17, 5, 26), Node(26, 0, 30), Node(3, -1, 25), Node(null, 1, 23), Node(27, 6, 17), Node(14, 1, 24), Node(28, -1, 3), Node(null, 80, 0), Node(20, 4, 11), Node(33, 6, 29), Node(24, 9, 33), Node(10, 7, 6), Node(0, 67, 1), Node(2, 15, 4), Node(32, 1, 14), Node(null, 1, 31), Node(29, 3, null), Node(9, -1, 28), Node(11, 5, 16), Node(8, 1, null), Node(6, 3, 7), Node(null, 8, 10), Node(23, 1, 12), Node(15, 5, 22), Node(7, 9, null), Node(21, 3, 5), Node(null, 3, 20), Node(16, 2, 15)),
8,
listOf(1, -1, 1, -1, 1, -1, 1)
),
Test(
listOf(Node(13, 80, 18), Node(18, 71, null), Node(5, 10, 19), Node(12, 1, 8), Node(19, 21, null), Node(31, 6, 2), Node(17, 5, 26), Node(26, 0, 30), Node(3, -1, 25), Node(null, 1, 23), Node(27, 6, 17), Node(14, 1, 24), Node(28, -1, 3), Node(null, 80, 0), Node(20, 4, 11), Node(33, 6, 29), Node(24, 9, 33), Node(10, 7, 6), Node(0, 67, 1), Node(2, 15, 4), Node(32, 1, 14), Node(null, 1, 31), Node(29, 3, null), Node(9, -1, 28), Node(11, 5, 16), Node(8, 1, null), Node(6, 3, 7), Node(null, 8, 10), Node(23, 1, 12), Node(15, 5, 22), Node(7, 9, null), Node(21, 3, 5), Node(null, 3, 20), Node(16, 2, 15)),
4,
listOf(1, 3, 6, 10, 15, 21)
),
Test(
listOf(Node(13, 80, 18), Node(18, 71, null), Node(5, 10, 19), Node(12, 1, 8), Node(19, 21, null), Node(31, 6, 2), Node(17, 5, 26), Node(26, 0, 30), Node(3, -1, 25), Node(null, 1, 23), Node(27, 6, 17), Node(14, 1, 24), Node(28, -1, 3), Node(null, 80, 0), Node(20, 4, 11), Node(33, 6, 29), Node(24, 9, 33), Node(10, 7, 6), Node(0, 67, 1), Node(2, 15, 4), Node(32, 1, 14), Node(null, 1, 31), Node(29, 3, null), Node(9, -1, 28), Node(11, 5, 16), Node(8, 1, null), Node(6, 3, 7), Node(null, 8, 10), Node(23, 1, 12), Node(15, 5, 22), Node(7, 9, null), Node(21, 3, 5), Node(null, 3, 20), Node(16, 2, 15)),
14,
listOf(3, 1, 4, 1, 5, 9, 2, 6, 5, 3)
),
Test(
listOf(Node(13, 80, 18), Node(18, 71, null), Node(5, 10, 19), Node(12, 1, 8), Node(19, 21, null), Node(31, 6, 2), Node(17, 5, 26), Node(26, 0, 30), Node(3, -1, 25), Node(null, 1, 23), Node(27, 6, 17), Node(14, 1, 24), Node(28, -1, 3), Node(null, 80, 0), Node(20, 4, 11), Node(33, 6, 29), Node(24, 9, 33), Node(10, 7, 6), Node(0, 67, 1), Node(2, 15, 4), Node(32, 1, 14), Node(null, 1, 31), Node(29, 3, null), Node(9, -1, 28), Node(11, 5, 16), Node(8, 1, null), Node(6, 3, 7), Node(null, 8, 10), Node(23, 1, 12), Node(15, 5, 22), Node(7, 9, null), Node(21, 3, 5), Node(null, 3, 20), Node(16, 2, 15)),
17,
listOf(8, 6, 7, 5, 3, 0, 9)
),
Test(
listOf(Node(4, 11, 0), Node(null, 22, 3), Node(null, 33, 3), Node(1, 44, 4), Node(3, 55, null), Node(7, 66, 7), Node(6, 77, 6)),
3,
listOf(22, 44, 55)
),
Test(
listOf(Node(null, -123, null)),
0,
listOf(-123)
)
)

var f:(List<List<Int?>>,Int)-> Sequence<Int?> =
{g,S->generateSequence(generateSequence(S){g[it][0]}.last()){g[it][2]}.map{g[it][1]}}

fun main(args: Array<String>) {
    for ((input, start, result) in TEST) {
        val out = f(input.map { it.toList() }, start).toList()
        if (out != result) {
            throw AssertionError("$input $start $result $out")
        }
    }
}

TIO

TryItOnline


generateSequenceが短くなったことを願っています
-jrtapsell

0

JavaScriptのES6、70の 63バイト

(x,i,a)=>(h=_=>i&&h(a(x[i].v),i=x[i].n))(x.map(_=>i=x[i].p||i))

テストケース:

F([undefined,{p:0,v:12,n:2},{p:1,v:99,n:3},{p:2,v:37,n:0}],1,alert)

alertあなたの関数の本体であることが必要であるとあなたのバイトの合計に対してカウント。
シャギー


+10 / -9はコンセンサスではありません。
シャギー

正確な+と-が表示されません。また、javascriptの意図した出力方法であり、出力に多少の遅延がある場合のみ
-l4m2
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.