Перестановка перестановки


9

Змагання

Для заданого набору з n цілих чисел напишіть програму, яка виведе його лексикографічний індекс.

Правила

  • Вхід повинен бути лише набором унікальних невід’ємних цілих чисел, розділених пробілами.
  • Вам слід вивести лексикографічний індекс (діапазон від 0 до n! -1 включно) перестановки.
  • Ніякі бібліотеки перестановки або вбудовані перестановки не можна використовувати.
  • Ви не можете генерувати набір перестановок або будь-який підмножина перестановок вхідних даних, щоб допомогти вам знайти індекс.
  • Ви також не можете збільшувати чи зменшувати задану перестановку до наступної / попередньої (лексикографічно) перестановки.
  • Бонусні бали (-10 байт), якщо ви знайдете спосіб виконати це, не використовуючи фактичних даних.
  • Час виконання має бути менше 1 хвилини для n = 100
  • Виграє найкоротший код за кількістю байтів
  • Вибір переможця у вівторок (22 липня 2014 р.)

Детальніше про перестановки

Приклади

0 1 2 --> 0
0 2 1 --> 1
1 0 2 --> 2
1 2 0 --> 3
2 0 1 --> 4
2 1 0 --> 5
0 1 2 3 4 5 6 7 --> 0
0 1 2 3 4 5 7 6 --> 1
0 1 2 3 4 6 5 7 --> 2
1 3 5 17        --> 0
781 780 779 13  --> 23
81 62 19 12 11 8 2 0 --> 40319
195 124 719 1 51 6 3 --> 4181

1
Чи можемо ми мати більше часу до вибору переможця? Три дні - це занадто мало часу.
xnor

Відповіді:


4

GolfScript, 12 (22 символи - 10 бонусів)

~]0\.,{.,@*\.(@$?@+\}*

Бонусні бали за невикористання фабрикантів. Вхід повинен бути вказаний на STDIN у форматі, відхиленому у запитанні. Ви можете спробувати код в Інтернеті .


Ха-ха, не зовсім те, що я шукав, коли я сказав "без використання фабрикантів", але я вважаю, що це враховується. Kudos
Kyle McCormick

4

CJam, 31 рік, з фабриками

q~]{__(f<0+:+\,,(;1+:**\(;}h]:+

Чому я все ще отримую заяву? Відповідь GolfScript можна переписати на CJam лише з 23 символами.
jimmy23013

6
Тому що людям подобається ваша відповідь.
seequ

1

Пітон 2 (77 = 87-10)

p=map(int,raw_input().split())
s=0
while p:s=s*len(p)+sorted(p).index(p.pop(0))
print s

Такі читабельні. Багато вбудованого Ого.

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

Замість того, щоб переглядати індекси масиву, ми неодноразово видаляємо перший елемент списку та обробляємо решта елементів. Вираз sorted(p).index(p.pop(0))підраховує кількість перетворень минулого першого індексу, займаючи його позицію у відсортованому списку, одночасно виконуючи видалення.

На жаль, мені довелося використовувати Python 2 і взяти ще 4 символи для raw_input(хоча -1 для print), оскільки в Python 3 map(int,...)виробляється об’єкт map, який не підтримує операції зі списком,


1

Pyth (13 = 23-10)

JVPwdWJ=Z+*ZlJXovNJ;J)Z

Порт моєї відповіді Python .

Переклад Python (з відфільтрованими нерелевантними матеріалами):

Z=0
J=rev(split(input()," "))
while J:
 Z=plus(times(Z,len(J)),index(order(lambda N:eval(N),J),J.pop()))
print(Z)

Числа вхідних значень залишаються рядками, але сортуються як int, використовуючи eval як ключ. Список перевернутий так, що popзаймає передню, а не задню.


1

Кобра - 202

Очевидно, що Кобра насправді не конкурує в цьому.

class P
    var n=0
    var t=CobraCore.commandLineArgs[1:]
    def main
        .f(.t[0:0])
    def f(l as List<of String>)
        if.t.count==l.count,print if(.t<>l,'',.n+=1)
        else,for i in.t.sorted,if i not in l,.f(l+[i])

0

J, 5 байт (15 - 10)

#\.#.+/@(<{.)\.

Це працює в O ( n 2 ) час і може легко обробити n = 100.

Використання

   f =: #\.#.+/@(<{.)\.
   f 0 1 2
0
   f 0 2 1
1
   f 1 0 2
2
   f 1 2 0
3
   f 2 0 1
4
   f 2 1 0
5
   f 0 1 2 3 4 5 6 7
0
   f 0 1 2 3 4 5 7 6
1
   f 0 1 2 3 4 6 5 7
2
   f 1 3 5 17
0
   f 781 780 779 13
23
   f 81 62 19 12 11 8 2 0
40319
   f 195 124 719 1 51 6 3
4181
   NB. A. is the builtin for permutation indexing
   timex 'r =: f 927 A. i. 100'
0.000161
   r
927

Пояснення

#\.#.+/@(<{.)\.  Input: array P
             \.  For each suffix of P
          {.       Take the head
         <         Test if it is greater than each of that suffix
     +/@           Sum, count the number of times it is greater
#\.              Get the length of each suffix of P
   #.            Convert to decimal using a mixed radix
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.