Роз'єднайте дані, подвійні між собою


12

Подвійно зв'язаний список - це структура даних, в якій кожен вузол має valueа також "посилання" на список previousі наступний nodesу списку. Наприклад, розглянемо наступні вузли зі значеннями 12, 99 та 37:

Тут вузли зі значеннями 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, 99, 1], [0, 37, null], [null, 12, 0]].

Змагання

Напишіть програму, яка приймає як вхід масив вузлів та індекс вузла та повертає у порядку списку значення вузлів у тому ж подвійному зв’язку списку.

Ускладнення

"Пам'ять" не завжди містить вузли лише одного списку. Він може містити кілька списків:

Наведений вище масив містить три подвійно пов'язані списки, кольорово кодовані для вашої зручності:

  1. Вузли в індексах 7, 10, 1, 4, 3, 12(показані тільки nextпосилання , щоб зменшити перешкоди, натисніть , щоб збільшити):

    Враховуючи цей масив і будь-який з цих індексів, ваша програма повинна повертати значення для того, щоб вони були [0, 1, 1, 2, 3, 5, 8].

  2. Вузол в індексі 9:

    Враховуючи індекс 9, ваша програма повинна повернутися [99].

  3. Вузли на індекси 11, 8, 0, 6, 2:

    Враховуючи один з цих показників, він повинен повернутися [2, 3, 5, 7, 11].

Правила

Вхідні дані

Ваша програма отримає як вхід:

  1. Список 𝒏 вузлів (3-кортежі, як описано вище), де 1 ≤ 𝒏 ≤ 1000, у будь-якому зручному форматі, наприклад, масив масивів, "плоский" масив цілих чисел довжиною 3𝒏 тощо.

    Елементи 3-кортежів можуть бути в будь-якому порядку:, ( prev value next )і ( next prev value )т. Д. Для кожного вузла prevі nextбуде null(або інше зручне значення, наприклад -1), що вказує на перший або останній вузол у подвійному зв’язку списку або на дійсний індекс список на основі 0 або 1, як зручно. valueбуде 32-розрядним цілим числом, який підписує, або найбільшим цілим типом, який підтримує ваша мова, залежно від того, яка є менша кількість.

  2. Індекс 𝒑 вузла у списку (1). Вказаний вузол може бути першим вузлом у подвійно зв'язаному списку, останнім вузлом, середнім вузлом або навіть єдиним вузлом.

Список вхідних даних (1) може містити патологічні дані (наприклад, цикли, вузли, на які вказують кілька інших вузлів тощо), але вхідний індекс (2) завжди вказуватиме на вузол, з якого може бути єдиний, добре сформований вихід. виведено.

Вихідні дані

Ваша програма повинна виводити значення вузлів подвійно пов'язаного списку, членом якого є вузол в індексі 𝒑, у порядку списку. Вихід може бути у будь-якому зручному форматі, але його дані повинні містити лише вузол values.

Перемога

Це . Найкоротша відповідь у байтах виграє. Застосовуються стандартні лазівки.

Тестові справи

Нижче кожен тестовий випадок має форму:

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

... де Xлітера для ідентифікації тестового випадку, другий рядок - список введення, третій рядок - вхідний індекс на основі 0, а четвертий - вихідний.

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
Йорданія


Чи дозволено введення у вигляді трьох масивів (один, який містить усі попередні вузли в порядку, одні значення та один наступний вузол), чи це занадто далеко від поняття кортежів?
Санчіз

@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

Хаскелл , 79 65 59 55 байт

-6 байт завдяки Brute Force .

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

Визначте функцію, !яка повторюється через вузли, починаючи з вузла, iі повертає список відвідуваних індексів. Він приймає другий аргумент, dякий вказує, який індекс "кортежу" використовувати як індекс наступного вузла ( 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

Спробуйте в Інтернеті!

Це майже відповідь Часа Брауна за мінусом цих гольфів:

  • Я повторно використовую n, зберігаючи завдання
  • Я зберігаю останнє дійсне п у ​​м, що дозволяє мені
  • розмістіть друк після призначення в рядку 3, врятувавши мене остаточний друк
  • Я використовую тільки ~ n замість - ~ n, тому що негативні значення такі ж правдиві, як і позитивні, врятуючи мене 2 символи.


2

MATL , 39 байт

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

Спробуйте в Інтернеті!

Майже прямий порт моєї відповіді Octave, але ця версія спочатку знаходить кінець, а потім працює назад, а не навпаки, що врятувало один байт.

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...(всі вузли в плоскому масиві), в порядку next, prev, то valueдля кожного вузла з -1 , використовуваним для припинення вузлів.


1

Python 2 , 81 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

Спробуйте в Інтернеті!

EDIT: Thx для містера Xcoder на 4 байти ...

Бере список кортежів [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масив, з першого стовпця попередник, у другому стовпці - значення, а в третьому - значення вузлів-наступника. Усі індекси вузлів базуються на 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

Котлін , 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")
        }
    }
}

ТІО

TryItOnline


Я просто хочу, щоб генерація
секвенції

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 не є єдиною думкою.
Кудлатий

Я не бачу точних + і - s. Крім того, призначений вихідний спосіб Javascript, і єдиний спосіб, коли вихід має деяку затримку
l4m2
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.