Сортуйте елементи залежно від залежності


12

Мета

Сортуйте перелік елементів, які гарантують, що кожен елемент у списку після визначених залежностей.

Вхідні дані

Масив масивів цілих чисел, де кожне ціле число вказує індекс елемента, заснований на 0 або 1 на основі 1, після чого цей елемент повинен надходити. Вхід може бути масивом або рядком або будь-яким іншим, що читається людиною.

Наприклад, вхід на основі 0:

[
  [ 2 ],    // item 0 comes after item 2
  [ 0, 3 ], // item 1 comes after item 0 and 3
  [ ],      // item 2 comes anywhere
  [ 2 ]     // item 3 comes after item 2
]

Припустимо, що немає кругових залежностей, завжди є хоча б одне дійсне замовлення.

Вихідні дані

Числа в порядку залежності. Неоднозначний наказ не повинен бути детермінованим. Вихідним може бути масив, текст або будь-що інше, що читається людиною.

У висновку має бути вказано лише одне замовлення, навіть якщо є кілька дійсних замовлень.

Можливі виходи для вищевказаного входу включають:

[ 2, 3, 0, 1 ]
[ 2, 0, 3, 1 ]

Оцінка балів

Функція або програма, яка завершує це в найменшій кількості байтів, виграє славу прийняття. Кінцевий термін - 6 днів.


4
Це називається Топологічне сортування для допитливих.
Роберт Фрейзер

Вхід може бути масивом або рядком або будь-яким іншим, що читається людиною Просто для переконання: чи може це бути двовимірний масив із нулями та одиницями, де один вказує на залежність, а нуль вказує на відсутність залежності?
Луїс Мендо

@DonMuesli, вибачте за пізню відповідь, але ні. Ідея виникла з кодової залежності. Якщо ви додали інший модуль коду, було б безвідповідально змінювати невідповідні модулі коду, щоб заявити, що вони не залежать від цього нового модуля.
Hand-E-Food

Це абсолютно має сенс. Чи не повинен Денніс бути переможцем?
Луїс Мендо

Так. Вибачте, пізня напружена ніч та поспіх на основі припущень.
Hand-E-Food

Відповіді:


3

Желе, 8 байт

ịÐL³ŒḊ€Ụ

Це засновано на (непроведеному) глибинному підході з відповіді Python @ xnor .

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

Як це працює

ịÐL³ŒḊ€Ụ  Main link. Input: A (list of dependencies)

 ÐL       Apply the atom to the left until a loop is reached, updating the left
          argument with the last result, and the right argument with the previous
          left argument.
ị         For each number in the left argument, replace it with the item at that
          index in the right argument.
   ³      Call the loop with left arg. A (implicit) and right arg. A (³).
    ŒḊ€   Compute the depth of each resulting, nested list.
       Ụ  Sort the indices of the list according to their values.

Чи справді ці 8 символів становитимуть 19 байт?
Hand-E-Food

@ Hand-E-Food Jelly використовує користувацьке кодування (не UTF 8), тому кожен символ є байтом
Луїс Мендо

@ Hand-E-Food Дон Мюслі правильний. Jelly використовує цю кодову сторінку за замовчуванням, яка кодує всі символи, які вона розуміє, як один байт кожен.
Денніс

7

Pyth, 21 байт

hf.A.e!f>xYTxkTbQ.plQ
                    Q  input
                   l   length of input array
                 .p    all permutations of [0, 1, ..., lQ-2, lQ-1]
hf                     find the first permutation for which...
    .e          Q        map over the input array with indices...
       f       b           find all elements in each input subarray where...
        >xYT                 index of dependency is greater than...
            xkT              index of item
      !                    check whether resulting array is falsy (empty)
  .A                     is the not-found check true for [.A]ll elements?

Тест:

llama@llama:~$ echo '[[2],[0,3],[],[2]]' | pyth -c 'hf.A.e!f>xYTxkTbQ.plQ' 
[2, 0, 3, 1]

7

Python 2, 73 байти

l=input()
f=lambda n:1+sum(map(f,l[n]))
print sorted(range(len(l)),key=f)

Сортуйте вершини за їхнім нащадком, який fобчислює рекурсивно. Якщо вершина вказує на іншу вершину, її нащадки включають загострену вершину та всіх нащадків цієї вершини, тому у неї суворо більше нащадків. Отже, вона розміщується пізніше, ніж загострена вершина в упорядкуванні, як бажано.

Кількість вершин нащадків - це одна для себе, плюс кількість нащадків кожного з її дітей. Зауважте, що нащадка може бути перерахована кілька разів, якщо до нього веде кілька шляхів.

Він також працював би на використаній глибині, а не на нащадках

f=lambda n:1+max(map(f,l[n]))

за винятком того, maxщо потрібно було б подати 0у порожній список.


2
Гарний алгоритм. Це набрало б 12 байтів і в Pyth, і в Jelly.
Денніс

4

Pyth, 19 байт

hf!s-V@LQT+k._T.plQ

Спробуйте в Інтернеті: Демонстрація

Пояснення:

hf!s-V@LQT+k._T.plQ   implicit: Q = input list
               .plQ   all permutations of [0, 1, ..., len(Q)-1]
 f                    filter for permutations T, which satisfy:
      @LQT               apply the permutation T to Q
                         (this are the dependencies)
            ._T          prefixes of T
          +k             insert a dummy object at the beginning
                         (these are the already used elements)
    -V                   vectorized subtraction of these lists
   s                     take all dependencies that survived
  !                      and check if none of them survived
h                    print the first filtered permutation

4

Баш, 35 байт

perl -pe's/^$/ /;s/\s/ $. /g'|tsort

Приклад виконання

I / O - 1-індексований. Кожен масив йде в окремий рядок, пробіл - як роздільник елементів.

$ echo $'4\n1\n\n3\n1 3 2' # [[4], [1], [], [3], [1, 3, 2]]
4
1

3
1 3 2
$ bash tsort <<< $'4\n1\n\n3\n1 3 2'
3
4
1
2
5

Як це працює

tsort- про що я дізнався у відповіді @ DigitalTrauma - читає пари жетонів, розділених пробілом, які вказують на часткове впорядкування, та друкує загальне впорядкування (у вигляді відсортованого списку всіх унікальних жетонів), що розширює вищезазначене часткове впорядкування.

Усі цифри на певній лінії супроводжуються або пробілом, або передачею рядків. s/\s/ $. /gЧастина команди Perl замінює пробільні символи з пропуском, номер рядка і інший простір, таким чином , переконавшись , що кожен п на лінії до передує до .

Нарешті, якщо рядок порожній (тобто складається лише з передачі рядка), s/^$/ /додає пробіл до нього. Таким чином, друга підстановка перетворює порожній рядок k у k k, переконуючись, що кожне ціле число зустрічається хоча б один раз у рядку, до якого проходить труба tsort.


Правильно, добре. Я думаю, ти tsortкраща / краща, ніж я :) Дякую за додаткове пояснення.
Цифрова травма

3

Bash + coreutils, 20 80

nl -v0 -ba|sed -r ':;s/(\S+\s+)(\S+) /\1\2\n\1 /;t;s/^\s*\S+\s*$/& &/'|tsort|tac

Введіть як розділені пробілом лінії, наприклад:

2
0 3

2
  • nl додає нульові індекси до всіх рядків
  • sed розбиває списки залежностей на прості пари залежностей і робить неповні залежності залежними від себе.
  • tsort робить необхідний топологічний сорт
  • tac ставить вихідний зворотний порядок

Ідеон. Ідея з тестом @Dennis


2

Python 2, 143 118 116 байт

Трохи більш випадковий підхід.

from random import*
l=input()
R=range(len(l))
a=R[:]
while any(set(l[a[i]])-set(a[:i])for i in R):shuffle(a)
print a

Зміни:

  • виправили це, і насправді зберегли деякі байти.
  • Збережено 2 байти (спасибі @Dennis)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.