Сортировка списка строк без использования встроенного метода сортировки


12

Целью этого Code Golf является создание программы, которая сортирует список строк (в порядке возрастания), без использования какого-либо встроенного метода сортировки (например, Array.Sort()в .NET, sort()в PHP, ...). Обратите внимание, что это ограничение исключает использование встроенного метода, который сортирует массив по убыванию, а затем переворачивает массив.

Некоторые детали:

  • Ваша программа должна запросить ввод, и этот ввод представляет собой список строк, содержащих только строчные буквы ASCII a-z, разделенные запятыми без пробелов. Например:

    code,sorting,hello,golf
    
  • Выходными данными должен быть заданный список строк, но отсортированный в порядке возрастания, по-прежнему без пробелов. Например:

    code,golf,hello,sorting
    

Ответы:


3

GolfScript, 26 25 байт

","/.,{{.2$<{\}*}*]}*","*

Прямая реализация Bubble Sort.

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

Как это устроено

","/     # Split the input string at commas.
.,       # Get the number of chunks.
{        # Do that many times:
  {      #   Reduce; for each element but the first:
    .2$< #     Push 1 if the last two strings are in descending order, 0 if not.
    {\}* #     Swap these strings that many times.
  }*]    #   Collect the strings dumped by reduce in an array.
}*       #
","*     # Join, separating by commas.

Ницца! Принимать это как ответ, потому что он короче, чем принятый в настоящее время.
ProgramFOX

10

Руби 76 54 51 символов

x=gets.scan /\w+/;$><<x.dup.map{x.delete(x.min)}*?,

1
Очень мило, богосорт : D
Ручка двери

1
Вау, теперь это еще интереснее! Мне пришлось посмотреть на это некоторое время, прежде чем я понял, что происходит. Полагаю, теперь это небольшой вариант сортировки выбора: P
дверная ручка

1
Так как предметы гарантированно будут альфа-символами:x=gets.scan /\w+/
Стивен Румбальски

7

к (16 символов)

Вероятно, на самом деле не соответствует духу проблемы. В k нет встроенного оператора сортировки . <xвозвращает список индексов элементов в x в отсортированном порядке.

{x@<x}[","\:0:0]

Ну, это своего рода встроенная сортировка, поэтому, к сожалению, я не могу пометить это как ответ. Мне нравится идея, однако, так +1!
Программа Fox


3

Рубин, 99 символов ( сортировка гномов )

a=gets.scan /\w+/
p=1
while a[p]
a[p]>a[p-1]?p+=2:(a[p],a[p-1]=a[p-1],a[p])
p-=1if p>1
end
$><<a*?,

Это едва ли превосходит мою реализацию сортировки пузырьков:

Рубин, 110 104 101 символов ( Bubble sort )

s=gets.scan /\w+/
(z=s.size).times{(0..(z-2)).map{|i|s[i],s[i+1]=s[i+1],s[i]if s[i]>s[i+1]}}
$><<s*?,

Это делает list.lengthитерации, потому что сценарий наихудшего случая берет list.length - 1итерации, и еще одна действительно не имеет значения, и экономит 2 символа.

Просто для удовольствия, версия Quicksort:

Рубин, 113 символов ( Quicksort )

q=->a{if a[1]
p=a.shift
l=[]
g=[]
a.map{|x|(x>p ?g:l).push x}
q[l]+[p]+q[g]
else
a
end}
$><<q[gets.scan /\w+/]*?,

Я обнаружил, что эта реализация сортировки gnome зацикливается бесконечно, когда входные элементы не все уникальны, например, ab b.
Скотт Лидли

3

Хаскелл, 141

import Data.List
m=minimum
s[]=[]
s l=m l:s(l\\[m l])
t[]=[]
t s=let(a,b)=span(/=',')s in a:t(drop 1 b)
main=interact$intercalate",".s.t.init

По крайней мере, это ... вроде как эффективно.


Вы можете сохранить 11 символов, используя сортировку выбора: m=minimum s[]=[] s l=m l:(s$l\\[m l])(замените строки 2–4 на эти строки).
user3389669

initНе представляется необходимыми , поскольку есть ни замыкающий ,, ни завершающий символ новой строки. t s=let(a,b)=span(/=',')s in a:t(drop 1 b)может быть сокращено с помощью шаблона охранника, используя (>',')и капельного пространство между 1 b: t s|(a,b)<-span(>',')s=a:t(drop 1b).
Лайкони

Использование вставки с функцией вставки x#(y:r)|y<x=y:x#r;x#r=x:rкороче. Он может быть использован непосредственно tи, поскольку он не используется (\\)и intercalate","может быть заменен tail.((',':)=<<), импорт может быть отброшен. Все вместе 101 байт: попробуйте онлайн!
Лайкони

2

vba, 165

Sub q()
c=","
s=InputBox("?")
Z=Split(s, c)
t=UBound(Z)
For i=1 To t-1
For j=i To t
If Z(i)>Z(j) Then a=Z(i):Z(i)=Z(j):Z(j)=a
Next
Next
Debug.Print Join(Z,c)
End Sub

Я считаю 165 символов ...
Дверная ручка

@ Doorknob, фиксированный счет ... Сценарий greasemonkey, очевидно, дал мне неправильный счет, когда я набирал код.
SeanC

1
Вы можете избавиться от пробела в этом Split.
Ry-

Использование c=","и вызов cдважды фактически увеличивает количество байтов в этом случае, добавляя 7 байтов к числу байтов, тогда как при использовании «,» дважды получит 6 байтов. Вы можете уменьшить свой байт-код, взяв ввод непосредственно из вызова sub ( sub q(s)) и предположив, что s имеет тип option \ string. Вы можете потерять еще один байт, изменив For i=1 toна for i=1To. Вы можете потерять 5 байтов, изменив Debug.Print Join...наDebug.?Join...
Тейлор Скотт

2

Scala, 122 байта

Как однострочник (88 байт):

.permutations.filter(_.sliding(2).map(w=>w(0)<w.last).fold(true)((a,b)=>a&&b)).toSeq(0)

(это будет сортировать список, просто делая list.permutations.fil...)

В качестве программы (122 байта):

println(readLine.split(",").toSeq.permutations.filter(_.sliding(2).map(w=>w(0)<w.last).fold(true)((a,b)=>a&&b)).toSeq(0))

Более длинная версия, если вы хотите, чтобы она читалась со стандартного ввода.

Это повторяет все перестановки данного списка, пока он не наткнется на отсортированный. Это не быстро, так как для сортировки списка из 10 элементов требуется около 12 секунд, а для 11 элементов - более минуты.

Элементы [Редактировать] должны быть уникальными или <могут быть заменены на <=. Также извините за некро.


1

JavaScript 128

a=prompt().split(',');b=[];for(i in a){b.push(a[i]);k=0;for(j in b){j=k;b[j]>a[i]?[c=b[j],b.splice(j,1),b.push(c)]:k++}}alert(b)

ДЕМО скрипка .

Я ищу способ устранить b.


Снимите []вокруг части после, ?чтобы сохранить 2
символа

@ Doorknob Я попробовал это прежде, чем я получу, SyntaxError: missing : in conditional expressionпотому что ?:;(сокращение if/else), как предполагается, принимает только две части кода для выполнения (то есть true?b++:b--;), используя [, ]является хаком, я все еще не уверен, почему это работает, я думаю, что его понимают как пустой массив объявление, как размещение случайной строки или числа в качестве отдельной команды. но вы все еще можете свободно высказываться.
Математический чиллер

Хм, полагаю, я ошибся. Оператор запятой может выполнять несколько фрагментов кода одновременно. Использование скобок работает, поэтому я предполагаю, что ?:приоритет оператора ниже, чем,
дверная ручка

Нет, ты пробовал? Скобки все еще работают ...
Дверная ручка

@ Doorknob ваше право , однако я пытался {, }и это не сработало - я получаю SyntaxError: missing : after property id. что касается приоритета, круглые скобки всегда первые. я все еще хотел бы upvote ....
математика чиллер

1

PHP 83 байта

<?for($x=fgetcsv(STDIN);$x;)${$x[0]>min($x)?x:a}[]=array_shift($x)?><?=join(~Ó,$a);

О (п 3 ) осуществление выбора вида. Это Óперсонаж 211; немного запятая.

Пример использования:

$ more in.dat
code,sorting,hello,golf

$ php list-sort.php < in.dat
code,golf,hello,sorting

1

Python 3 (80 символов)

l=input().split(',')
m=[]
while l:m+=[l.pop(l.index(min(l)))]
print(','.join(m))

Вот вариант оператора while равной длины:

while l:x=min(l);m+=[x];l.remove(x)

1

Mathematica 66 56

Row[#[[Ordering@#]]&[InputString[]~StringSplit~","],","]

Некоторые другие решения без встроенного символа Ordering:

Богосорт: 84 74

NestWhile[RandomSample,InputString[]~StringSplit~",",!OrderedQ@#&]~Row~","

Пузырьковая сортировка: 93 83

Row[InputString[]~StringSplit~","//.{x___,i_,j_,y___}/;j~Order~i==1:>{x,j,i,y},","]

Другое решение, столь же неэффективное, как bogosort: 82 72

#~Row~","&/@Permutations[InputString[]~StringSplit~","]~Select~OrderedQ;

1

Python 3.5+, 73 байта

Это черпает вдохновение из ответа Стивена Румбальски, но использует понимание списка вместо цикла времени; количество итераций берется из скопированного списка, lпоэтому для этого требуются дополнительные обобщения распаковки и Python 3.5

l=input().split(',');print(*[l.pop(l.index(min(l)))for _ in[*l]],sep=',')

0

р

Bubble Sort: 122 118 символов

a=scan(,"",sep=",");h=T;while(h){h=F;for(i in 1:(length(a)-1)){j=i+1;if(a[i]>a[j]){a[j:i]=a[i:j];h=T}}};cat(a,sep=",")

Богосорт: 100 знаков

a=scan(,"",sep=",");while(any(apply(embed(a,2),1,function(x)x[1]<x[2]))){a=sample(a)};cat(a,sep=",")

0

Perl, 159

perl -F"," -lape "$m=$m<length()?length():$m for@F;$_{10**(2*$m)*sprintf'0.'.'%02d'x$m,map-96+ord,split//}=$_ for@F;$_=join',',map$_{$_+0},grep exists$_{$_+0},'0'.1..'0'.10**100"

У этого никогда не было шансов на победу, но я решил поделиться им, потому что мне понравилась логика, даже если это беспорядок :) Идея, стоящая за этим, состоит в том, чтобы преобразовать каждое слово в целое число (сделано с помощью функции ord ), мы сохраняем число в качестве ключа в хэше, а строку - в качестве значения, а затем мы все больше перебираем все целые числа (в данном случае 1..10 ** 100) и таким образом сортируем наши строки.

ПРЕДУПРЕЖДЕНИЕ . Не запускайте этот код на своем компьютере, поскольку он перебирает триллионы + целых чисел. Если вы хотите проверить это, вы можете снизить верхний предел диапазона и ввести недлинные строки. Если по какой-либо причине это противоречит правилам, пожалуйста, дайте мне знать, и я удалю запись!


0

JS: 107 символов - Bubble Sort

a=prompt().split(/,/);for(i=a.length;i--;)for(j=0;j<i;)a[j]>a[j+1]?[b=a[j],a[j]=a[++j],a[j]=b]:j++;alert(a)

Я посмотрел на ответ @ tryToGetProgrammingStraight и попытался улучшить его, но в итоге реализовал его немного по-другому.


0

Java, 134 байта

Метод, который реализует сортировку Gnome.

void s(String[]a){int m=a.length-1,i=0;while(i<m){while(i>=0&&a[i].compareTo(a[i+1])>0){String t=a[i];a[i]=a[i+1];a[i+1]=t;i--;}i++;}}

0

Swift, 101 байт

func s(a:[String])->[String]{return a.count<2 ? a:(s(a.filter{$0<a[0]})+[a[0]]+s(a.filter{$0>a[0]}))}

Ungolfed:

//quicksort
func sort(a:[String]) -> [String]
{
    //return the array if its length is less than or equal to 1
    if a.count <= 1
    {
        return a
    }
    //choose the first element as pivot
    let pivot = a[0]
    //retrieve all elements less than the pivot
    let left = a.filter{ $0 < pivot }
    //retrieve all elements greater than the pivot
    let right = a.filter{ $0 > pivot }
    //sort the left partition, append a new array containing the pivot,
    //append the sorted right partition
    return sort(left) + Array<String>(arrayLiteral: pivot) + sort(right)
}

Это не принимает и не возвращает строки в указанном формате через запятую.
Лайкони

0

𝔼𝕊𝕄𝕚𝕟, 24 символа / 30 байтов (неконкурентный)

ï⇔Ĕ⍪;↻ïꝈ)ΞÿѨŗ ï,⇀$≔МƵï;Ξ

Try it here (Firefox only).

Используя сортировку выбора!

объяснение

ï⇔Ĕ⍪;↻ïꝈ)ΞÿѨŗ ï,⇀$≔МƵï;Ξ // implicit: ï=input, Ξ=[]
ï⇔Ĕ⍪;                    // split ï along commas and set it to ï
     ↻ïꝈ)                // while ï's length > 0
         Ξÿ              // push to Ξ:
           Ѩŗ ï,⇀$≔МƵï;  // removed minimum item(s) from ï using builtin
                       Ξ // get sorted array

В основном рекурсивно удаляет и помещает минимум из входных данных в другой массив.


0

Цейлон (Богосорт), 119

String s(String i)=>",".join([*i.split(','.equals)].permutations.select((p)=>!any{for([x,y]in p.paired)y<x})[0]else[]);

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

Я нашел permutationsметод и, таким образом, получил Bogosort (неслучайный вариант).

Отформатировано и прокомментировано:

// a function `s` mapping a String `i` to a String
String s(String i) =>
    // the end result is created by joining the iterable in (...).
    ",".join(
        // take the input, split it on commas, make the result a sequence.
        [*
            i.split(','.equals)   // → {String+}
           ]                      // → [String+]
        // get the iterable of all permutations of this sequence.
        // Yes, this is an iterable of O(n!) sequences (though likely
        // lazily computed, we don't need all in memory at once).
        .permutations              // → {[String+]*}
        // filter this iterable for ordered sequences.
        // Using select instead of filter makes this
        // eager instead of lazy, so we are actually iterating
        // through all n! sequences, and storing the ordered
        // ones. (All of those are equal.)
        .select(
            // this is our function to check whether this sequence
            // is ordered in ascending order.
            (p)=>
               // return if none of the following iterable of booleans is true.
                !any {
                   // This is a for-comprehension. Inside an named argument list
                   // (what we have here, although there is no name) for a
                   // function which wants an iterable, this becomes an iterable,
                   // lazily built from the existing iterable p.paired,
                   // which is just an iterable with all pairs of subsequent
                   // elements.
                      for([x,y] in p.paired)
                        // for each such pair, we evaluate this expression, which
                        // is true when the sequence is not ordered correctly.
                           y < x         // → Boolean
                        // → {Boolean*}
                    }  //   → Boolean
                 //  → Boolean([String+])
               ) // → [[String+]*]
         // we now have a sequence of (correctly sorted) sequences.
         // just take the first one.
         // If we had used `.filter` before, this would have to be `.first`.
               [0]    // → [String+]|Null
         // in case this is null, which can only happen if the original array was
         // empty, so there were no permutations, just use the empty sequence
         //  again. (Actually, split never returns an empty array, so this can't
         //  happen, but the type checker can't know that.)
               else []    // → [String*]
    // so that is what we pass to the join method.
        )   // → String
    ;

Без форматирования и разбора он становится всего 90 байтов:

String[]s(String[]i)=>i.permutations.select((p)=>!any{for([x,y]in p.paired)y<x})[0]else[];

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



0

ruby -plaF, 70 байт

o=[]
$F.map{|s|i=o;s.bytes{|b|i=i[b]=[*i[b]]};i[0]=s<<?,}
$_=o*''
chop

O (n), если вы делаете вид, что изменение размера и сжатие массива бесплатны (это очень не бесплатно).

Мы создаем глубоко и неравномерно вложенный массив o, помещая строку с байтами b 1 , b 2 ... b n в массив в позиции o [b 1 ] [b 2 ] ... [b n ]. Результат выглядит как[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,["a,",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, ["abc,"], ["abd,"], ["abe,"]], ["ac,"], ["ad,"]],, ["c,"]]

Затем мы выравниваем и выводим его.


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