Я работаю над проблемой 24 из Project Euler, которая выглядит следующим образом:
Перестановка - это упорядоченное расположение объектов. Например, 3124 - это одна из возможных перестановок цифр 1, 2, 3 и 4. Если все перестановки перечислены в числовом или алфавитном порядке, мы называем это лексикографическим порядком. Лексикографические перестановки 0, 1 и 2:
012 021 102 120 201 210
Какая миллионная лексикографическая перестановка цифр 0, 1, 2, 3, 4, 5, 6, 7, 8 и 9?
Я пытаюсь решить эту проблему с помощью Haskell и начал с подхода грубой силы:
import Data.List
(sort . permutation) [0..9] !! 999999
Но это занимает слишком много времени, и мне интересно, не потому ли, что программа сначала получает все перестановки, затем сортирует их все, а затем, наконец, берет миллионный элемент, что намного больше, чем нужно.
Итак, я подумал, что могу ускорить процесс, если напишу функцию, которая перечисляет перестановки уже в лексикографическом порядке, чтобы мы могли просто остановиться на миллионном элементе и получить ответ.
Алгоритм, который я имею в виду, состоит в том, чтобы сначала отсортировать входной список x
, затем взять первый (самый маленький) элемент и добавить его к перестановкам остальных элементов в лексикографическом порядке. Эти упорядочения могут быть найдены путем рекурсивного вызова исходной функции на уже отсортированном хвосте x
(что означает, что наша исходная функция должна иметь способ отмечать, отсортирован ли список ввода). Затем мы переходим к следующему по величине элементу x
и так далее, пока не получим полный упорядоченный список. К сожалению, я все еще новичок в Haskell, и мои попытки написать эту функцию не увенчались успехом. Есть какие-нибудь намеки на то, как это можно сделать?