Вступление
Лексикографические перестановки списка с n элементами могут быть пронумерованы от 0 до n ! - 1. Например, 3! = 6 перестановок (1,2,3)
будет (1,2,3)
, (1,3,2)
, (2,1,3)
, (2,3,1)
, (3,1,2)
, (3,2,1)
.
Когда к списку применяется перестановка, ее элементы упорядочиваются в том же порядке, что и числа в перестановке. Например, применяя перестановку (2,3,1)
к l = (a,b,c)
выходам (l[2],l[3],l[1]) = (b,c,a)
.
Инверсия перестановки определяется как перестановка, которая переворачивает эту операцию, то есть применение перестановки, а затем ее обратной (или наоборот) не изменяет массив. Например, обратное значение (2,3,1)
равно (3,1,2)
, поскольку применяется к (b,c,a)
доходностям (a,b,c)
.
Кроме того, обратная перестановка, примененная к самой перестановке, дает целые числа 1… n . Например, обращаясь (3,1,2)
к (2,3,1)
доходам (1,2,3)
.
Теперь определим функцию revind ( x ) как индекс обратной перестановки перестановки с индексом x . (Это A056019 , если вам интересно.)
Поскольку перестановка с индексом i изменяет только последние k элементов списка, если 0 ≤ i < k !, Мы можем добавить любое количество элементов в начало списка, не влияя на revind ( i ). Поэтому длина списка не влияет на результат.
Вызов
Ваша задача - реализовать revind ( x ). Вы напишете полную программу или функцию, которая принимает одно неотрицательное целое число x в качестве входных данных / аргументов и выводит / возвращает результат как одно неотрицательное целое число.
Вход и выход могут быть 0-индексированными или 1-индексированными, но это должно быть согласовано между ними.
Встроенные функции, которые генерируют перестановки по индексу, возвращают индекс перестановки или находят обратную перестановку, запрещены. (Встроенные функции, которые генерируют все перестановки или следующую перестановку, разрешены.)
Применяются стандартные правила игры в гольф .
Примеры
Приведенные ниже примеры имеют индекс 0.
Input Output
0 0
1 1
2 2
3 4
4 3
5 5
6 6
13 10
42 51
100 41
1000 3628
2000 3974
10000 30593
100000 303016
Ссылочная реализация (Python 3)
def revind(n):
from math import factorial
from itertools import permutations, count
l = next(filter(lambda x: factorial(x) > n, count(1)))
pms = list(permutations(range(l)))
return [k for k in range(len(pms)) if tuple(pms[n][i] for i in pms[k]) == pms[0]][0]
источник
(a,b,c)
крайне неясным. Пожалуйста, включите правильное объяснение того, что такое обратная перестановка.Ụ
(повышение класса), который сортирует индексы массива по их соответствующим значениям. Это происходит, чтобы инвертировать перестановку 1,…, n , но это не работает для других перестановок. ЭтоỤ
запрещенный встроенный?Ответы:
Желе , 6 байт
Ввод / вывод использует индексирование на основе 1. Очень медленный и жаждущий памяти.
верификация
Пока вход не превышает 8! = 40320 , достаточно рассмотреть все перестановки массива [1,…, 8] . Для последнего теста достаточно перестановок [1,…, 9] .
С немного измененным кодом, который учитывает только перестановки первых 8 или 9 положительных целых чисел, вы можете попробовать это онлайн!или проверьте все оставшиеся тестовые случаи .
Как это устроено
Альтернативный подход, 6 байтов (неверно)
Это так же долго, и он использует запрещенные атом повышения
Ụ
, но это (возможно) более идиоматично.Предваряя 8 (или 9 для последнего контрольного примера), мы можем попробовать онлайн!
Как это устроено
источник
Mathematica, 74 байта
Использует 1-индексацию. Очень неэффективно. (использует ~ 11 ГБ памяти при входе
11
)объяснение
Создайте список от 1 до N. Сохраните это в
j
.Найти все перестановки
j
. Храните это вi
.Сохраните
Position
функцию вk
. (чтобы уменьшить количество байтов приPosition
повторном использовании )Найти обратную перестановку N-й перестановки.
Найти
k
(Position
) обратной перестановки вi
(все перестановки)Используя встроенные модули,
4643 байта1-индексироваться.
источник
MATL , 15 байт
Вход и выход основаны на 1.
Аналогичен ответу CJam от @ MartinEnder , но находит обратную перестановку путем составления всех возможных перестановок с той, которая указана на входе, и выяснения, которая стала перестановкой тождеств.
В онлайн-компиляторе не хватает памяти для ввода
10
.Попробуйте онлайн!
объяснение
источник
Pyth, 12 байт
Тестирование
0 проиндексировано.
Объяснение:
источник
05AB1E ,
1413 байтОчень неэффективная память.Теперь еще больше неэффективной памяти (но на 1 байт короче).Диапазон на основе 0
Использует кодировку CP-1252 .
Попробуйте онлайн! или как модифицированный набор тестов
объяснение
источник
CJam , 16 байтов
Индексы начинаются с 0.
Попробуйте онлайн!
Я не становлюсь более неэффективным, чем это ... не
8
хватает памяти с настройками Java по умолчанию для входов больше (но в принципе работает для произвольных входов, учитывая достаточное количество вселенных времени и памяти).объяснение
источник
GAP , 108 байт
1-индексироваться. Новые строки не учитываются, они не нужны. Мне не обязательно назначать конечную функцию имени, но ...
h
является функцией карри, которая берет список перестановок и индекс в этом списке и возвращает индекс обратной перестановки. Без ограничений я бы просто обошелсяPosition(l,l[n]^-1)
.f
вызывает эту функцию с отсортированными перестановками достаточно большой симметричной группы и заданнымn
.Я мог бы просто написать
SymmetricGroup(n)
, тогда функция могла бы быть вычислена для значений до 9. Поскольку решения уже намного меньше, я предпочитаю делать это:Действительно эффективное 0-индексированное решение, которое работает для аргументов ниже 99! (и может работать для аргументов ниже 999! за счет одного байта):
После удаления пробела это имеет 255 байтов.
источник
JavaScript (ES6),
163120110 байт0 индексированные. Работает путем преобразования индекса в перестановку, инвертирования его и последующего преобразования обратно в индекс. Редактировать: Экономия около 25% путем
f
инвертирования и перестановки перестановок, а затемg
преобразования обратной перестановки обратно в индекс. Сохранение еще 10 байтов путем объединения двух рекурсивных вызовов в одну функцию. Ungolfed:источник
f
инвертировать перестановку вместоg
…J,
5550 байтОсновано на эссе индексу перестановок .
Этот код требует только памяти порядка,
n
но использует больше времени, так как он сортирует списокn
раз и ищет егоn
по каждому индексу.Используя встроенную функцию,
/:
которая может найти оценку списка и обратную перестановку, существует 42-байтовое решение, которое является более эффективным.Эта версия требует только 44 секунд для вычисления последнего контрольного примера по сравнению с другим, который требует 105 секунд.
использование
источник
Желе ,
14 139 байт-4 байта благодаря @Dennis (который он продолжил, используя быстрый
⁺
в своем ответе )Еще одна очень медленная реализация.
Здесь используется индексация на основе 1, поэтому ожидаемые результаты:
Нет смысла даже размещать онлайн-ссылку на IDE, поскольку TIO убивает при входе
10
. Локальные результаты (последний очень медленный и требует тонны памяти!):Как?
Примечание: нет необходимости сортировать перестановки, так как мы используем один и тот же порядок как для нахождения перестановки, так и для обратной.
источник
ÇịịÇ$iR
?R
перед темŒ!
подразумевается, поэтомуŒ!ịịŒ!$iR
должен делать эту работу.Python 2,
116114 байтrepl.it
0 на основе. Медленно и память голодна, но мало байтов.
Не используя перестановочных функций; и память и время эффективно.
289285 байт-4 байта благодаря @Christian Sievers (полная перестановка уже сформирована)
Я знаю, что это кодовый гольф, но я думаю, что @ Pietu1998 также заинтересован в эффективных реализациях.
Смотрите это в действии на repl.it
Хотя для этого используется больше байтов, чем для эталонной реализации, для сравнения
n=5000000
:f
является функцией обратного индекса.f
сначала получает следующий факториал вышеn
,t
и целое число, факториал которого,x
вызываяh(n)
, и устанавливаетg=range(x)
элементы, которые будут составлять перестановку,o=g[:]
и держатель перестановки,r=[]
Затем он создает перестановку по индексу
n
, поочередноpop
извлекая индексы факториального базового представления изn
элементовo
и добавляя их кr
. Факториальное базовое представление находится с помощью div и modn
сt
гдеt
делится наx
иx
уменьшается до1
.Наконец, он находит индекс обратной перестановки, вызывая
i
с обратной перестановкой,[r.index(v)for v in g]
h
является функцией двойного назначения для вычисления факториала неотрицательного целого числа или для вычисления следующего факториала выше неотрицательного целого числа и целого числа, которое делает этот факториал.В этом состоянии по умолчанию ,
v=1
и это делает последний путем умноженияv
наx
(также изначально1
) и приращенииx
до тех пор ,n
пока по крайней мере, большой, то она возвращаетсяv
иx-1
в кортеже.Вычислить
n!
один вызов,h(n,0)
который умножаетсяx
(изначально1
) наn
и уменьшаетсяn
до тех пор,n
пока0
он не вернетсяx
.i
обеспечивает лексикографическом индекс перестановки,p
, детали[0,1,...n]
путем сложения продуктов факториала факторного основания каждого индекс,h(len(p)-j-1,0)
и сколько элементов справа от индекса меньше , чем значение в этом индексе,sum(k<p[j]for k in p[j+1:])
.источник
t/=x
.(r+o)
наr
.Python 2,
130129 байтисточник
На самом деле ,
1811 байтовЭтот ответ использует алгоритм в ответе Денниса «Желе», но имеет индекс 0. Предложения по игре в гольф приветствуются! Попробуйте онлайн!
Ungolfing
источник