Я должен отсортировать список номеров, но я супер ленивый. Очень сложно понять, как поменять местами все числа, пока они не будут в порядке возрастания, поэтому я разработал собственный алгоритм, который будет гарантировать сортировку нового списка ». Вот как это работает:
Для списка размера N нам понадобится N-1 итераций. На каждой итерации
Проверьте, меньше ли N-й номер, чем N + 1-й номер. Если это так, то эти два числа уже отсортированы, и мы можем пропустить эту итерацию.
Если это не так, то вам нужно постоянно уменьшать первые N чисел, пока эти два числа не будут в порядке.
Давайте возьмем конкретный пример. Допустим, вход был
10 5 7 6 1
На первой итерации мы сравним 10 и 5. 10 больше 5, поэтому мы уменьшаем его до тех пор, пока оно не станет меньше:
4 5 7 6 1
Теперь мы сравним 5 и 7. 5 меньше, чем 7, поэтому нам не нужно ничего делать на этой итерации. Итак, мы переходим к следующему и сравниваем 7 и 6. 7 больше 6, поэтому мы уменьшаем первые три числа до 6, и получаем:
2 3 5 6 1
Теперь мы сравниваем 6 и 1. Опять же, 6 больше 1, поэтому мы уменьшаем первые четыре числа до тех пор, пока оно не станет меньше 1, и мы получим это:
-4 -3 -1 0 1
И мы сделали! Теперь наш список в идеальном порядке. И, чтобы сделать вещи еще лучше, нам нужно было только перебирать список N-1 раз, так что этот алгоритм сортирует списки за O (N-1) время, которое, я уверен, является самым быстрым алгоритмом.
Ваша задача на сегодня - реализовать эту Ленивую Сорт. Ваша программа или функция получит массив целых чисел в любом стандартном формате, который вам нравится, и вы должны выполнить эту отложенную сортировку и вернуть новый «отсортированный» список. Массив никогда не будет пустым или содержит нецелые числа.
Вот некоторые примеры:
Input: 10 5 7 6 1
Output: -4 -3 -1 0 1
Input: 3 2 1
Output: -1 0 1
Input: 1 2 3
Output: 1 2 3
Input: 19
Output: 19
Input: 1 1 1 1 1 1 1 1 1
Output: -7 -6 -5 -4 -3 -2 -1 0 1
Input: 5 7 11 6 16 2 9 16 6 16
Output: -27 -25 -21 -20 -10 -9 -2 5 6 16
Input: -8 17 9 7
Output: -20 5 6 7
Как всегда, это код-гольф , поэтому напишите самую короткую программу, какую только сможете!
¹ Это не означает, что это звучит, как это означает, но это технически верно
² Я шучу, пожалуйста, не ненавидь меня
источник
<sarcasm>
Этот алгоритм сортировки на самом деле все еще имеетO(N^2)
временную сложность, потому что вы должны пройти через все ранее доступные элементы в списке, чтобы уменьшить их. Вместо этого я рекомендую просмотреть список в обратном порядке и при необходимости уменьшать только одно число на шаг. Это даст вам истиннуюO(N)
сложность!</sarcasm>
O(n^2)
с точки зрения доступа к памяти, но неO(n)
для сравнения?O(N^2)
.Ответы:
Желе ,
14 12 119 байт-2 байта благодаря ETHproductions (используйте минимальную диаду,
«
)Монадическая ссылка, берущая и возвращающая списки целых чисел.
Попробуйте онлайн! или посмотрите набор тестов .
Я действительно не думаю, что этого достаточно Lazy ™!
Как?
источник
Haskell , 40 байт
Попробуйте онлайн!
источник
JavaScript (ES6), 61 байт
Контрольные примеры
Показать фрагмент кода
источник
Желе , 12 байт
Попробуйте онлайн!
Как это работает
Основная идея в игре заключается в следующем: если вы инвертируете входной и выходной массивы, выводом будет просто ввод с каждой дельтой 0 или более, замененной -1. Например:
источник
к, 20 байтов
Попробуйте онлайн.
Объяснение:
источник
Haskell, 56 байт
Попробуйте онлайн!
Оставьте первую часть списка в параметре
a
. На каждом шаге добавляйте следующий элементx
в конецa
и увеличивайте все элементы до минимума(y-x-1)
и0
.источник
Python , 54 байта
Попробуйте онлайн!
Принимает входной splatted как
f(1,2,3)
. Выводит список. Использует экспоненциальное время.источник
C #, 76 байт
Это изменяет список на месте. Он проходит по списку в обратном порядке и сохраняет промежуточную сумму дельты для каждого числа.
источник
JavaScript (ES6), 59 байт
источник
f=
для ответов JS, чтобы сохранить два байтаf(a)
), поэтому ей все равно нужно имя.Brain-Flak , 153 байта
Попробуйте онлайн!
Это включает в себя
+1
для-r
флага.источник
R, 56 байт
function(s){s-c(rev(cumsum(rev(pmax(0,-diff(s)+1)))),0)}
источник
diff
, я пытался выяснить, как заставить это работать ... Кстати, вы можете избавиться от скобок вокруг тела функции на -2 байта, но еще лучше, вы можете использоватьs=scan()
вместо функции определение, чтобы сохранить еще несколько байтов. Было бы замечательно, если бы вы включили ссылку « Попробовать онлайн», чтобы другие люди могли убедиться, что этот код работает для всех тестовых случаев.JavaScript (ES6), 68 байт
Вход и выход - это массив целых чисел.
Тестовый фрагмент
источник
JavaScript (ES6), 50 байт
Объяснение:
Это рекурсивное решение, которое сначала клонирует массив, затем уменьшает все значения до тех пор, пока элемент не станет больше или равен следующему элементу в массиве.
Функция вызывает себя до тех пор, пока какие-либо элементы не работают. Когда элементы окончательно отсортированы, клон возвращается. (Мы не можем вернуть сам массив, потому что
some()
метод уменьшил бы все его элементы, отключив их на -1.)Тестовые случаи:
источник
SWI-Пролог, 194 байта
Может быть в состоянии попробовать это онлайн здесь: http://swish.swi-prolog.org/p/LazySort.pl
Вы спрашиваете,
l(L, [10,5,7,6,1]).
что говорит "решить для L, где L - ленивый вариант этого списка".Две функции:
l
azysorted (A, B) - указывает, что A является lazysorted версией B, если они оба являются пустыми списками, или если A можно получить путем обращения B, вызова вспомогательной функции для обхода списка и выполнения вычитания с помощью аккумулятора толкая каждое значение ниже, чем предыдущее, и возвращая результат обратно вправо.f
помощник сопоставляет два списка, значение предыдущего числа в списке и накопитель скользящей разности, и решает, для нового значения текущей позиции списка, являющегося исходным значением минус накопитель разности, опционально минус новое значение, требуемое для принудительной установки этого значения. значение ниже предыдущего числа в списке, иf
должно быть рекурсивно вычислено для конца списка с теперь увеличенным аккумулятором разницы.Скриншот тестовых случаев на Swish:
источник
JavaScript (ES6), 61 байт
Не самое короткое решение, но я не мог упустить возможность использовать
reduceRight
.источник
C # (.NET Core) ,
89 88 8679 байтовfor
s.Попробуйте онлайн!
Сначала
for
выполняется итерация по массиву, затем вычисляется уменьшение и, наконец, второе,for
при необходимости, уменьшение элементов доi
позиции th.Допустимо ли просто изменить исходный массив вместо возврата нового (все еще привыкая к правилам)?
источник