При сортировке блинов единственной допустимой операцией является обращение элементов некоторого префикса последовательности в обратном порядке. Или подумайте о стопке блинов: вставляем где-то в стопку шпатель и переворачиваем все блины над шпателем.
Например, последовательность 6 5 4 1 2 3
может быть отсортирована, сначала перевернув первые 6
элементы (всю последовательность), получив промежуточный результат 3 2 1 4 5 6
, а затем перевернув первые 3
элементы, достигнув 1 2 3 4 5 6
.
Поскольку существует только одна операция, весь процесс сортировки может быть описан последовательностью целых чисел, где каждое целое число является количеством элементов / блинов, которые должны включать pr flip. Для примера выше последовательность сортировки была бы 6 3
.
Другой пример: 4 2 3 1
можно отсортировать с помощью 4 2 3 2
. Вот промежуточные результаты:
4 2 3 1
flip 4: 1 3 2 4
flip 2: 3 1 2 4
flip 3: 2 1 3 4
flip 2: 1 2 3 4
Задание:
Напишите программу, которая берет список целых чисел и печатает правильную последовательность сортировки блинов.
Список для сортировки может быть либо разделенным пробелами списком из stdin, либо аргументами командной строки. Распечатайте список так, как это удобно, если он несколько читабелен.
Это кодегольф!
Редактировать:
Как я уже сказал в комментариях, вам не нужно оптимизировать вывод (найти самую короткую последовательность - NP-сложная задача ). Однако я только что понял, что дешевым решением будет выбрасывать случайные числа, пока вы не получите желаемый результат (тип [new?] Bogosort). Ни один из ответов до сих пор не сделал этого, поэтому я сейчас заявляю, что ваш алгоритм не должен полагаться на какую-либо (псевдо-) случайность .
Пока вы все бьетесь, вот вариант bogopancakesort в Ruby 2.0 (60 символов), чтобы втирать его:
a=$*.map &:to_i
a=a[0,p(v=rand(a.size)+1)].reverse+a[v..-1]while a!=a.sort
4 3 2 1
вместо4 2 3 1
Ответы:
GolfScript, 34/21 символ
(Спасибо @PeterTaylor за то, что отрубили 4 символа)
Онлайн тест
Более короткая версия из 21 символа работает только для списков с уникальными элементами
Онлайн тест
Обе версии дают неоптимальные решения.
Объяснение для более короткого решения:
Это использует другой алгоритм для большинства других опубликованных. По сути, он захватывает наименьший элемент списка и двумя щелчками перемещает его вперед, сохраняя порядок других элементов.
Чтобы переместить n-й элемент вперед:
Он повторяет эту операцию для каждого элемента по порядку и заканчивается обратным отсортированным списком. Затем он переворачивает весь список, чтобы оставить его полностью отсортированным.
Фактически алгоритм представляет собой вариант решения Python из 90 символов (мое собственное, конечно):
источник
&
нигде не используете , так что вы должны иметь возможность заменитьs
while&
и удалить пробелы.^
в качестве переменной в задаче Фибоначчи;) Спасибо за совет!3 2 1
я получаю131211
что не правильно.2 1 1
больше не могут быть отсортированы.Питон,
9190 символовПереверните самый большой блин наверх, затем переверните весь стек. Удалите самый большой блин снизу и повторите.
i
это индекс самого большого блина.L=L[:i:-1]+L[:i]
переворачиваетi+1
блины, переворачиваетlen(L)
блины, затем бросает последний блин.источник
print
делает вывод нечитаемым (1 байт сохранен :)Ruby 1,9 -
1098879 символовГораздо более компактная версия, основанная на отличном Python-решении Кейта:
Оригинальная версия:
Если вам не нужны ложные операции (реверсирование стеков размера 1 или реверсирование одного и того же стека дважды подряд), вы можете сделать его немного короче (96 символов):
Принимает несортированный список как аргументы командной строки. Пример использования:
источник
GolfScript,
3129 символовДругое решение GolfScript, также может быть протестировано в Интернете .
Предыдущая версия:
Как это работает: он переворачивает самый крупный элемент наверх, а затем на последнее место в списке. Поскольку теперь он находится в правильном положении, мы можем удалить его из списка.
источник
Perl,
103100 символовОжидается ввод в командной строке.
Решения, которые он печатает, явно неоптимальны. (У меня была программа с намного более хорошим выводом около 24 символов назад ....)
Логика довольно интересная. Он начинается с каталогизации индекса каждого элемента, если он находится в отсортированном порядке. Затем он перебирает этот каталог справа налево. Таким образом, применение переворота включает в себя настройку индексов ниже предельного значения, вместо фактического перемещения значений. После некоторых ошибок мне также удалось сохранить несколько символов, выполнив оба переворачивания на одну итерацию одновременно.
источник
Python 2 (254)
Простой BFS-поиск, некоторые вещи встроены, вероятно, могут быть сжаты больше без изменения стиля поиска. Надеюсь, это покажет, как начать играть в гольф (слишком много, чтобы быть простым комментарием).
Использование:
(2 пробела = табуляция)
источник
sys.exit()
на1/0
(в Codegolf вы никогда не заботитесь о том, что печатается в stderr ...).print s[::-1];1/0
бы побрить несколько символов.4 2 3 1
дарами2 3 2 4
, что на самом деле неверно.4 2 3 1
->2 4 3 1
->3 4 2 1
->4 3 2 1
->1 2 3 4
Python2: 120
Он не эффективен: он не найдет наилучшую последовательность сортировки, и данная последовательность может даже содержать no-ops (т. Е. Переключать только первый элемент), тем не менее, вывод верен.
Выход дается в виде:
Какой должна быть прочитана как последовательность перестроек:
n_1 n_2 n_3 n_4 n_5 n_6 ...
. Если вы хотите получить вывод вроде:n_1 n_2 n_3 n_4 n_5 n_6 ...
Просто добавьте запятую в
print
заявлении.источник
[:i][::-1]
->[i-1::-1]
,[:u][::-1]
->[u-1::-1]
, сохраняет 2 символаL[:i]=L[i-1::-1];L[:u]=[u-1::-1]
сохраняет еще 3 символаPython - 282 персонажа
Мой первый в мире кодовый гольф; У меня нет иллюзий, что я выиграю , но мне было очень весело. Если вы дадите одно-символьное имя, вам будет страшно читать, позвольте мне сказать вам! Это запускается из командной строки, пример реализации ниже:
Нет ничего особенно особенного или изобретательного в том, как я подошел к этому, но FAQ предлагает опубликовать версию без игры в гольф для заинтересованных читателей, поэтому я сделал это ниже:
Основной алгоритм, который я использовал, - это тот, который упоминается в статье вики, связанной с вопросом :
источник
t=p[:x]
t=t[::-1]
(16 + отступ) можно уменьшить доt=p[:x][::-1]
(13) или дажеt=p[x-1::-1]
(12). Инлайн все, что вы можете:p=p[x-1::-1]+p[x:]
len(a)-n
становится-n
;p=p[-n-1::-1]+p[-n:]
, Далее в гольф, используя правильные операции:p=p[~n::-1]+p[-n:]
map(int,sys.argv[1:])
, что сейчас делают ваши первые 6 строк.i=x=g=0
работает, но вы все равно должны сократить количество переменных. Я скажу вам одну вещь: это единственная запись наC # -
264 259 252237 символовИспользует самый простой алгоритм и производит правильный вывод без избыточных переворотов. Можно было бы сбрить 7 символов, если бы я позволил включить 1 (не флипс) в вывод, но это ужасно.
Я прибегал к использованию
goto
для максимального гольфа. Также сохранил некоторые символы, позволив ему выполнять не переворачивать (но не печатать их).Последнее улучшение: сохранение входного массива в виде строк вместо преобразования в целые.
Ungolfed:
Вот мое первоначальное решение, без гольфа (264 символа в гольфе):
источник
Haskell ,
7271 байтПопробуйте онлайн! Находит максимум, переворачивает его назад и рекурсивно сортирует оставшийся список.
Редактировать: -1 байт благодаря BMO
источник
Perl 5.10 (или выше), 66 байт
Включает
+3
в довести язык до уровня Perl 5,10 считается свободным-n
use 5.10.0
Запустите с вводом одной строкой на STDIN:
Сортирует список, многократно находя любую инверсию, переворачивая ее на передний план, затем переворачивая инверсию и переворачивая все обратно в прежнее положение. И это равносильно обмену инверсией, поэтому мне не нужно менять местами (что неудобно в строках, поскольку при этом меняются цифры преобразованных значений, например,
12
в21
).источник
C # - 229
читаемая версия
источник