DropSort это как горячо


41

Как описано в этом вопросе :

Dropsort, разработанный Дэвидом Морганом-Маром, является примером «алгоритма сортировки» по линейному времени, который создает список, который фактически отсортирован, но содержит только некоторые из исходных элементов. Любой элемент, который не меньше, чем максимум элементов, предшествующих ему, просто удаляется из списка и удаляется.

Для того, чтобы использовать один из своих тестовых примеров, ввод {1, 2, 5, 4, 3, 7}урожайности {1, 2, 5, 7}, как 4и 3оба упали за то , что меньше , чем ранее «сортируются» значение, 5.

Мы не хотим «сортировать» алгоритмы, мы хотим, чтобы они были реальными. Поэтому я хочу, чтобы вы написали программу, которая, учитывая список чисел, выводит список списков DropSorted (чтобы быть полным алгоритмом сортировки, нам нужно объединить эти списки, но объединение двух отсортированных списков уже было сделано ранее, и просить вас сделать это снова - это в значительной степени задавать два вопроса, так что этот вопрос, в частности, является этапом «разделения» нашей полной DropSort).

Однако расположение и содержание наших списков имеет решающее значение. Вывод вашей программы должен быть эквивалентен выводу DropSort, за которым следует DropSort отброшенных значений и так далее, пока у вас не будет только списка отсортированных цепочек. Снова заимствуем существующий набор тестов (и добавим еще два):

Input                  -> Output
{1, 2, 5, 4, 3, 7}     -> {{1, 2, 5, 7}, {4}, {3}}
{10, -1, 12}           -> {{10, 12}, {-1}}
{-7, -8, -5, 0, -1, 1} -> {{-7, -5, 0, 1}, {-8, -1}}
{9, 8, 7, 6, 5}        -> {{9}, {8}, {7}, {6}, {5}}
{10, 13, 17, 21}       -> {{10, 13, 17, 21}}
{10, 10, 10, 9, 10}    -> {{10, 10, 10, 10}, {9}}  //Note equivalent values aren't dropped
{5, 4, 3, 8, 7, 6}     -> {{5, 8}, {4, 7}, {3, 6}}
{0, 2, 5, 4, 0, 7}     -> {{0, 2, 5, 7}, {4}, {0}}

Вы можете предположить, что ввод не пуст.

Это , поэтому применяются стандартные правила!


Можем ли мы выводить как [5, 4, 3, 8, 7, 6] -> [5, 8], [4,3,7,6]?
г-н Xcoder

5
@Xcoder, ну, я не против синтаксиса, но вам все равно придется отсортировать второй список (и разделить его в этом случае). Знание, когда остановиться, является частью проблемы;). И Стьюи, я не знаю, что тебе сказать. Я видел проблему DropSort и думал, что это звучит весело. Есть ли шанс, что вы использовали свою машину времени, чтобы вырваться вперед и увидеть этот вопрос? Только не используйте его, чтобы увидеть лучший ответ!
Лорд Фаркуад

Обратите внимание, что добавление сортировки остатков выводит решения из линейного времени.
Ikegami

Должен {3,4,5,3,4,5,3,4,5}привести к {{3,4,5,5,5},{3,4,4},{3}}?
QBrute

@QBrute Я думаю, что это правильно.
Лорд Фаркваад

Ответы:


10

MATL , 15 10 9 байт

5 байт, используя идею @beaker о кумулятивном максимуме

t"ttY>=&)

Ввод представляет собой числовой вектор строки в формате [1, 2, 5, 4, 3, 7](запятые не обязательны). Вывод содержит списки, разделенные символами новой строки, с номерами в каждом списке, разделенными пробелами.

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

Для данного массива код выбирает из него каждую запись, равную кумулятивному максимуму до этой записи.

Например, учитывая

1 2 5 4 3 7

код выбирает первую, вторую, третью и шестую записи:

1 2 5     7

Затем процесс повторяется для подмассива, образованного оставшимися записями (в исходном порядке):

      4 3

Это необходимо сделать до тех пор, пока подмассив оставшихся записей не станет пустым. Верхняя граница необходимого количества итераций - размер ввода. Последние итерации могут не понадобиться. В этом случае они работают с пустым массивом, создавая дополнительные пустые массивы.

В конце концов, стек содержит требуемые массивы и, возможно, несколько пустых массивов, которые вообще не отображаются.

t        % Implicit input. Duplicate
"        % Do as many times as the input size
  tt     %   Duplicate twice
  Y>     %   Cumulative maximum
  =      %   Compare for equality. Will be used as logical index
  &)     %   Two-output indexing: pushes indexed subarray, and then
         %   a subarray with the remaining entries
         % End (implicit)
         % Display stack (implicit). Empty arrays are not displayed

23

Haskell, 67 59 58 байт

(q:r)!x|x<last q=q:r!x|1<2=(q++[x]):r
_!x=[[x]]
foldl(!)[]

Объяснение: Учитывая список списков (которые уже отсортированы) и значение x, !оператор помещает xв конец первого списка, последний элемент которого меньше или равен x. Если такого списка не существует, список [x]помещается в конец.

Попробуйте онлайн.


3
Это невероятно умное решение. Честно говоря, я ожидал, что большинство людей просто и снова будут отбрасывать DropSort, пока не останется ничего, но я надеялся, что кто-то придумает более творческий подход.
Лорд Фаркваад

13

Шелуха , 10 байт

hUmü<¡Ṡ-ü<

Попробуйте онлайн!

Это сочетание другого моей шелухи ответа и Haskell ответа XNOR в . Дубликат ü<кажется неуклюжим, но я не знаю, как от него избавиться ...

объяснение

Функция ü<переводится nubBy(>)в Haskell. Он пересекает список слева направо, сохраняя те элементы, для которых ранее ни один элемент не был строго больше. Другими словами, он выполняет дропсорт. Оставшиеся элементы получаются путем взятия разницы списков исходного списка и результата ü<.

hUmü<¡Ṡ-ü<  Implicit input, say x = [2,3,5,4,4,2,7].
     ¡      Iterate
      Ṡ-    list difference between argument
        ü<  and its dropsort: [[2,3,5,4,4,2,7],[4,4,2],[2],[],[],[],...
  m         Map
   ü<       dropsort: [[2,3,5,7],[4,4],[2],[],[],[],...
 U          Prefix of unique elements: [[2,3,5,7],[4,4],[2],[]]
h           Drop last element: [[2,3,5,7],[4,4],[2]]

10
Лучший ответ Outgolfs на 33% "Я не знаю, это кажется неуклюжим"
Лорд Фаркуаад


7

Шелуха , 16 байт

hUm₁≤¡₁>
ṠfSz⁰G▲

Попробуйте онлайн!

объяснение

Эта первая строка является основной функцией, а вторая - вспомогательной функцией более высокого порядка (она принимает функцию в качестве аргумента и возвращает новую функцию). Это доступно по нижнему индексу . Идея состоит в том, что ₁≤выполняет DropSort и ₁>дает оставшиеся элементы.

ṠfSz⁰G▲  Helper function, takes binary function p (as ⁰) and list x (implicit).
         For example, p = (≤) and x = [2,4,3,4,5,2].
     G▲  Left scan on x with maximum: [2,4,4,4,5,5].
  Sz     Zip with x
    ⁰    using the function p: [1,1,0,1,1,0].
Ṡf       Keep elements of x at truthy indices: [2,4,4,5].

В основной функции мы ₁>повторяем функцию остатков и применяем функцию дропсорта ₁≤к результатам.

hUm₁≤¡₁>  Main function, implicit list argument, say x = [2,4,3,4,5,2].
     ¡    Iterate
      ₁>  the leftovers function: [[2,4,3,4,5,2],[3,2],[2],[],[],[],...
  m       Map
   ₁≤     the dropsort function: [[2,4,4,5],[3],[2],[],[],[],...
 U        Prefix of unique elements: [[2,4,4,5],[3],[2],[]]
h         Drop last element (an empty list): [[2,4,4,5],[3],[2]]

Husk - это новое желе ...
Эрик Outgolfer

1
@EriktheOutgolfer Побит MATL. : /
Zgarb

6

Python 3 , 131 112 103 95 байт

Большое спасибо @Mr. Xcoder для сокрушительного 19 байтов!

Большое спасибо @ovs за потрясающие 17 байтов!

def f(x):
 a,*x=x or[0];m=[a];d=[]
 for i in x:[m,d][i<m[-1]]+=i,
 return[m]+(x and(d>[])*f(d))

Попробуйте онлайн!

Объяснение:

def f(x):               #recursive function taking list, returns list of lists 
 if len(x)<2:return[x]  #for a single element return [element] 
 m=[x[0]];d=[]          #initialize main and dropped lists
 for i in x[1:]:[m,d][i<m[-1]]+=[i]  #append elements from the argument list accordingly into main and dropped list 
 return[m]+(d>[])*list(f(d)) #add main-list along with further evaluated dropped-list(recursived) into a list of lists

2
116 байт. if-elseМогут быть свернуты в [m,d][i<m[-1]]+=[i].
г-н Xcoder

Вау, спасибо большое ... Я пробовал эту [m,d]штуку, но она как-то не работала ....
officialaimm

1
113 байтов . (len(d)>0)есть bool(d), потому что пустые списки являются ложными в Python. +1, отличное решение!
г-н Xcoder


2
i,это просто сокращение (i,), которое содержит кортеж a. a,*x = x or [0]это расширенная распаковка python3 . Вот полезный пост SO на эту тему с некоторыми примерами.
овс

6

Haskell , 113 107 102 92 байта

import Data.List
a!(b:c)|b<last a=a!c|1>0=a++[b]!c
a!b=a
g x@(b:c)|i<-[b]!c=i:g(x\\i)
g x=[]

Попробуйте онлайн!

Это чувствует себя действительно долго.

объяснение

!выполняет сортировку по списку, а #собирает обрезки. gзатем повторно применяется #до тех пор, пока список не станет пустым, записывая результаты в список.


1
Замена head aс a!!0сохранением байта.
Томсминг

5

APL, 27 байт

{⍵≡⍬:⍬⋄(⊂X/⍵),∇⍵/⍨~X←⍵≥⌈\⍵}

Объяснение:

  • ⍵≡⍬:⍬: если вход пуст, вернуть пустой список
  • X←⍵≥⌈\⍵: все числа больше или равны рабочему максимуму
  • (⊂X/⍵): список этих номеров,
  • ∇⍵/⍨~X: с последующим результатом выполнения этой функции на оставшихся номерах

Сохранить байт с {⍵≡⍬:⍬⋄(⊂⍵~r),∇r←⍵/⍨⍵<⌈\⍵}. Мортен обеспокоен отсутствием ответа на его электронные письма. Все в порядке?
Адам

О, Боже. Я рад, что здесь вам удалось. Увидимся на следующей неделе.
Адам

4

JavaScript (ES6), 64 байта

f=(a,l,r=[])=>a+a&&[a.filter(e=>e<l?!r.push(e):(l=e,1)),...f(r)]

Ungolfed:

f=(a,l,r=[])=>
  a+a&&                                    //any elements left?
  [a.filter(                               //filter elements that are in order,
    e=>e<l?!r.push(e):(l=e,1)              //push unsorted elements to r
   ),                                      //push() returns the new length of the array,
                                           //... so !push() will always return false
   ...f(r)                                 //recurse on r
  ]


1
На долю секунды я подумал, что ?!это какой-то новый оператор ...
Нил

Ха, да, я должен был включить объяснение. Сейчас добавлено.
Рик Хичкок,


(i,n,o=[])=>[i.filter(a=>(n||a)<=a?(n=a,1):!o.push([a])),...o]Видимо, великие умы думают (вроде) одинаково. К сожалению, я не могу сбрить больше байтов ... Просто отметив, что вы можете удалить f=свой код, и, возможно, мой код может дать вам некоторые идеи о том, как играть в свой гольф еще больше.
Дэвид Арчибальд

Спасибо, @DavidArchibald. Я не могу удалить f=из своего кода, потому что это рекурсивно. Ваш интересный подход, но он не работает для пары тестовых случаев. Например, он возвращается [[5,8],[4],[3],[7],[6]] для предпоследнего случая.
Рик Хичкок,

4

R 61 байт

f=function(x)if(sum(x|1)){print(x[b<-x==cummax(x)]);f(x[!b])}

Попробуйте онлайн!

Рекурсивная функция. sum(x|1)является условным обозначением length(x), поэтому эта рекурсия будет выполняться до тех пор, пока она не xбудет пустой. cummaxпринимает кумулятивный максимум x, который затем сравнивается с xснова. Это создает логический вектор длины x, где все ИСТИНЫ соответствуют отсортированным значениям. Мы используем это, чтобы взять подмножество xи printэто. Затем функция вызывается снова в оставшейся части x.


4

Ява 8, 182 179 177 байт

import java.util.*;l->{List r=new Stack(),t;for(int p,i,x;l.size()>0;)for(p=l.get(0),r.add(t=new Stack()),i=0;i<l.size();p=x)if((x=l.get(i++))>=p)t.add(l.remove(--i));return r;}

-3 байта благодаря @Nevay .
-2 байта при использовании StackвместоVector .

Объяснение:

Попробуй это здесь.

import java.util.*;            // Required import for List and Vector
l->{                           // Method with ArrayList<Integer> parameter and List return-type
  List r=new Stack(),          //  Return-List
       t;                      //  Temp-List
  for(int p,i,x;               //  Some temp integers
      l.size()>0;)             //  Loop (1) as long as there are still items left in the list
    for(p=l.get(0),            //   Set `p` to the first item of the list
        r.add(t=new Stack()),  //   Add a new inner List to the result-List
        i=0;i<l.size();        //   Inner loop (2) from 0 to the size of the list (exclusive)
         p=x)                  //     After every iteration, save the previous value in `p`
      if((x=l.get(i++))>=p)    //    If the current item is equal or larger than the previous:
        t.add(l.remove(--i));  //     Add it to the temp-List, and remove it from the input-List
                               //   End of inner loop (2) (implicit / single-line body)
                               //  End of loop (1) (implicit / single-line body)
  return r;                    //  Return result-List
}                              // End of method

Можете ли вы использовать try{}catch{}вместо проверки, l.size()чтобы сохранить некоторые?
TheLethalCoder

1
Вы можете начать внутренний цикл 0и удалить скобки внешнего цикла for l->{List r=new Vector(),t;for(int p,i,x;l.size()>0;)for(p=l.get(0),r.add(t=new Vector()),i=0;i<l.size();p=x)if((x=l.get(i++))>=p)t.add(l.remove(--i));return r;}(-3 байта).
17

3

C #, 188 203 байта

int[][]f(int[]a){int[]t=a.Where((n,i)=>i<1||n>=a[i-1]).ToArray(),m=a.Where((n,i)=>i>0&&n<a[i-1]).ToArray();var s=new int[][]{t}.ToList();if(m.Any())s.AddRange(f(m));return s.ToArray();}

Количество байтов включает +18 для:

using System.Linq;

Попробуйте онлайн!


@RickHitchcock Исправлено по стоимости 15 байт! Хорошее место.
TheLethalCoder

Хорошая работа
Рик Хичкок

3

C ++ 14, 118 108 байт

Используя алгоритм из ответа Haskell w0lf .

Как неназванная родовая лямбда. Первый параметр является контейнером значений для droport (например vector<int>), а второй параметр требует совместимого пустого контейнера контейнеров (например,vector<vector<int>> ) для возвращаемого значения через ссылку.

В первой версии программы был R.clear;()первый оператор, поэтому контейнер контейнеров не должен быть пустым. Питер Кордес подумал, что это может быть включено в спецификацию, поэтому для этого уронил 10 байт.

[](auto A,auto&R){for(auto x:A){for(auto&D:R)if(D.back()<x){D.push_back(x);goto F;}R.emplace_back(1,x);F:;}}

Попробуйте онлайн!

Ungolfed:

[](auto A,auto&R){
 for(auto x:A){       //foreach item
  for(auto&D:R)       //foreach result list
   if(D.back()<x){    //x bigger than last element
    D.push_back(x);   //add x
    goto F;           //break and jump over the emplace
   }
  R.emplace_back(1,x);//create new list with this element
  F:;
 }
}

Вы, вероятно, можете обойтись без пропуска R.clear()и просто потребовать, чтобы вызывающая сторона начала с пустого контейнера.
Питер Кордес

@PeterCordes хорошая идея, я мог бы переписать мои другие ответы C ++, которые показали возвращение через параметр ссылки.
Карл Напф

2

Python 2 , 88 байт

-4 байта благодаря Арнольду Палмеру

b,r=input(),[]
for i in b:
 for l in r:
	if l[-1]<=i:l+=[i];break
 else:r+=[[i]]
print r

Попробуйте онлайн!

Решение, похожее на haskell @ w0lf [ответ] [1]

Редкий вариант использования для for-else строительства

Перебирать отсортированные списки for l in r(пустые в начале).
Если элемент (из ввода) iбольше, чем последний элемент списка l[-1], добавить элемент в список l+=[i], разбить.
Если список не был принят, добавьте новый список с этими элементамиr+=[[i]]


1
88 байтов , просто вынимая его из функции.
Арнольд Палмер

1

R, незавершенное производство (89, но не удалось)

Проведение некоторой работы здесь, потому что я загнал себя в угол, используя %in%(Это не удается на дублирующих записях, в частности, в последнем тестовом примере), и мне нужно пойти и заняться другими делами сейчас, но это здесь, если кто-то хочет использовать это:

z=function(x){if(length(x)){a=x[x>=cummax(x)]
append(list(a),z(x[!(x%in%a)]))}else{NULL}}

Ungolfed:

z=function(x){
  if(length(x)){
    a=x[x>=cummax(x)]
    append(list(a),z(x[!(x%in%a)]))
  } else {
    NULL
  }
}

Вы, вероятно, должны удалить это в настоящее время, чтобы не получить отрицательных голосов, пока вы исправляете это.
Джузеппе

1
z=function(x)"if"(sum(x|1),{a=x[(i=x>=cummax(x))] c(list(a),z(x[!i]))},NULL)работы
Джузеппе

пробел между ]и cявляется новой
Джузеппе

Я никогда не видел "if"прежде, но я довольно новичок в R гольф. Вы должны опубликовать как свой собственный ответ, и я могу снять мой. Мне нравится то, что вы сделали с iиндексом, чтобы обойти %in%проблему.
Алекс

Нет, ты сделал всю тяжелую работу! Я не мог обернуть голову вокруг этой проблемы, пока не увидел вашу реализацию - я бы никогда не вспомнил cummax!
Джузеппе

1

JavaScript (ES6), 71 70 68 байт

a=>a.map(n=>(o.find(b=>[...b].pop()<=n)||(n=[n],o)).push(n),o=[])&&o

Довольно просто, просто перебирает массив, ищет первый внутренний массив, чье последнее значение равно <=следующему значению, для удаления, если его не существует, добавляет новый внутренний массив со следующим значением к выводу, в противном случае добавляет следующее значение к первому найден внутренний массив, соответствующий условию.

Обновления

Благодаря Neil, сохранены три байта преобразования (...,o)в ...&&oи повторно организовать обратный вызов , map()чтобы быть более компактным.

f=a=>a.map(n=>(o.find(b=>[...b].pop()<=n)||(n=[n],o)).push(n),o=[])&&o;[[1,2,5,4,3,7],[10,-1,12],[-7,-8,-5,0,-1,1],[9,8,7,6,5],[10,13,17,21],[10,10,10,9,10],[5,4,3,8,7,6],[0,2,5,4,0,7]].map(f).map(JSON.stringify).map(v=>console.log(v))
.as-console-wrapper{max-height:100%!important}


1
&&oна байт короче (,o).
Нил

@ Нил Гах! Отличный улов, спасибо
Патрик Робертс

1
Мне нравится твой [...b].pop(), но я думаю, что (o.find(b=>[...b].pop()<=n)||(n=[n],o)).push(n)спасает тебя один или два байта.
Нил

В таком случае, я чувствую себя обязанным пометить это как сообщение сообщества ... черт
Патрик Робертс

Просто из-за пары твиков? Это все тот же код ...
Нил,


1

C (gcc) , 176 175 173 байта

#define P(x)printf("%d ",t=x);
l[2][99];t;x;i;j;w;main(a){while(scanf("%d",*l+w)>0)++w;while(i=w){P(l[a=!a][w=0])for(j=1;j<i;++j){x=l[a][j];x<t?l[!a][w++]=x:P(x)}puts("");}}

Попробуйте онлайн!

Несколько читаемая версия:

#define P(x)printf("%d ",t=x);
l[2][99];t;x;i;j;w;
main(a)
{
    while(scanf("%d",*l+w)>0)++w;
    while(i=w)
    {
        P(l[a=!a][w=0])
        for(j=1;j<i;++j)
        {
            x=l[a][j];
            x<t?l[!a][w++]=x:P(x)
        }
        puts("");
    }
}


Э-э, конечно, как глупо - спасибо!
Феликс Пальмен,

1

PHP, 91 103 96 85 байт

(Отредактировано, чтобы добавить 12 символов print_r($r);для соответствия требованию к выводу)
(Отредактировано, чтобы удалить 7 байтов при разрешении ошибок PHP)
(Отредактировано, чтобы удалить 11 байтов при дальнейшем выполнении задания)

while($a){$b=$d=[];foreach($a as$i)${max($b)>$i?d:b}[]=$i;$a=$d;$r[]=$b;}print_r($r);

Учитывая вход $a, он дает результат$r

Милая:

while ($a) {
    $b = $d = [];
    foreach ($a as $i) {
        ${max($b) > $i ? d : b}[] = $i;
    }
    $a   = $d;
    $r[] = $b;
}

Псевдорекурсивный внешний цикл инициализирует пустые массивы keep $bи discard $d, затем выполняет основной цикл сортировки отбрасыванием, наконец устанавливая отбрасывания как новый вход и добавляя keep к результату.$r


1

PHP , 102 байта , 98 байтов

<?php function s($i){static$s;foreach($i as$v)${$v<max($l)?f:l}[]=$v;$s[]=$l;!$f?:s($f);return$s;}

Попробуйте онлайн!

-4 байта, благодаря @Umbrella

объяснение

<?php

Функция принимает входной список в виде массива.

function s($i) {

$s, который станет окончательно возвращенным списком списков, объявляется статическим. Это расширяет область его действия для всех вызовов этой функции, позволяя вызывать функцию рекурсивно без необходимости передавать этот список результатов в качестве аргумента или возвращать его.

    static $s;

Переберите каждое значение в списке.

    foreach ($i as $v)

Это меньше, чем самый большой текущий член списка?

        $v < max($l) ?

Да, внесите его в список $fдля дальнейшей сортировки.

                        $f[] = $v :

Нет, поместите это в список $l.

                        $l[] = $v;

Нажмите список $lна список списков.

    $s[] = $l;

Если в списке есть что-нибудь $f, отправьте его снова для дальнейшей сортировки.

    !$f ?: s($f);

Вернуть список списков.

    return $s;
}

1
С учетом 31 символа, который я оставил <?php function d($a){return$r;}, вы от всей души раздавили меня. Кроме того, я просто понял, что мы оба забыли вывести.
Зонт

Я играть в гольф моего решения вниз , чтобы попытаться бить твои , не используя ваши и я нашел способ ваших может быть улучшен: Я думаю , что вы можете сохранить четыре символа, заменив $v<max($l)?$f[]=$v:$l[]=$v;с ${$v<max($l)?f:l}[]=$v;- по крайней мере, она работает в моих тестах.
Зонт

@ Зонт, не возвращается, выводит ??? И спасибо за эти 4 байта. Я никогда не думал о такой работе, используя код для оценки имени переменной. Я должен помнить, чтобы учесть это в будущих задачах… 🤔
WebSmithery

Обнаружил, что консенсус, кажется, принимает возвращение в качестве вывода: codegolf.meta.stackexchange.com/questions/2447/…
Umbrella

0

Sage, 102 байта

def f(w,a=[]):
 for x in w:
  q,c=exists(a,lambda b:b[-1]<=x)
  if q:c+=[x]
  else:a+=[[x]]
 return a

Очень похоже на @Dead опоссума ответ .
Дописывает каждый член xиз wк первому списку в a{списка списков} с xбольшим , чем в последнем элементе.
если нет, присоединяет [x]к a.

Мне бы очень понравилось, если бы existsвернули, aесли ничего не нашли! Также пытаюсь применить однострочную идею @ officialaimm ...

Вопрос: Если бы я удалил свой код из функции, мне пришлось бы назначить wввод правильно? Так сэкономит ли это байты?


0

Окамль , 69 62 байта

let rec d=function h::i::t when h>i->d(h::t)|h::t->h::d t|x->x

Объяснение:

let rec d = function (* Implicitly take an list as a parameter *)
    (* If the list starts with two elements h and i and h is greater than i, drop i and sort the list starting with h and the rest t *)
    | h::i::t when h > i -> d (h::t) 
    (* If h is not greater than i, make a new list starting with h and a tail containing the drop sorted rest *)
    | h::t -> h::d t
    (* If none of the cases apply, the list is empty. *)
    | x -> x

0

APL, 100 88 83 79 78 57 56 77 76 байт

{(E/⍵),⊂⍵/⍨~E←(⍬≢⍴)¨⍵}∘{⍵≡(S←¯1↓⍵),⊃⊃⌽⍵:⍵⋄∇S,⊃⌽⍵}{⍵≡X←⍵/⍨~V←⍵≠⌈\⍵:⍵⋄X(∇V/⍵)}

-0 байт благодаря Kritixi Lithos ...

Попробуйте онлайн!

Должен быть лучший способ сделать это ( есть ). Любые советы очень ценятся и приветствуются.

Как?

(Обратите внимание, что некоторые из этих объяснений могут быть неправильными, так как я забыл, как это работает)

{⍵≡X←⍵/⍨~V←⍵≠⌈\⍵:⍵⋄X(∇V/⍵)} - separate the argument into nested drop-sorts
{⍵≡(S←¯1↓⍵),⊃⊃⌽⍵:⍵⋄∇S,⊃⌽⍵}  - un-nesting (passed the result of the above)
{(E/⍵),⊂⍵/⍨~E←(⍬≢⍴)¨⍵}∘     - fixing array mishaps (passed the result of the above)

{⍬≢⍴⍵}может стать(⍬≢⍴)
Kritixi Lithos

Уже сделал это, не видя вашего комментария,
Zacharý

Какова цель {(⍵/⍨~E),⊂⍵/⍨E←(⍬≡⍴)¨⍵}? Кажется, он отделен от всего остального
Kritixi Lithos

Без него первый контрольный пример был бы чем-то вроде [[1,2,5,7],[4],3], а не обязательным [[1,2,5,7],[4],[3]].
Захари

Вы могли бы сократить этот dfn до просто(,¨)
Kritixi Lithos


0

JavaScript (Node.js) , 125 109 106 байт

- 16 18 байт из Захари

-1, удалив {и }изменив инкремент, чтобы включить «установить последний на текущий»

m=x=>{z=[[],[]];l=NaN;for(i=0;i<x.length;l=x[i++])if(l>x[i])z[1].push(x[i]);else z[0].push(x[i]);return z}

По сути, спрашивает, является ли текущий элемент больше, чем последний элемент, добавьте в первый список. В противном случае добавьте ко второму.

Во время этого выяснилось, что сравнение с любым числом NaNвсегда будет результатом false. Интересный!

Объяснение:

m = x => {                         // Create function
  z = [[], []];                      // Initialize dropsort output
  l = NaN;                           // Initialize last element
  for (i = 0; i < x.length; l=x[i++])// For each item in input...
    if (l > x[i])                    // If current item is greater than previous
      z[1].push(x[i]);               // Then add it to the first part of output
    else                             // Elsewise
      z[0].push(x[i]);               // Add it to the nonordered part of the dropsort
                                     // Set last item to current item
  }                                  // Repeat
  return z                           // Return finished dropsort
}                                    // End function

Попробуйте онлайн!


Вы должны использовать var?
Захари

@ Захари, дай мне проверить!
Стэн Струм

Парены не нужны x.
Захари
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.