इसे क्रमबद्ध करें, जल्दी!


27

ठीक है ... वहाँ 59 (अब 60) प्रश्न के टैग हैं , लेकिन कोई सरल quicksorts।

यह तय होना चाहिए।

क्विकॉर्टम से अपरिचित लोगों के लिए , यहाँ एक विराम है , जो कि विकिपीडिया के सौजन्य से है-

  1. एक तत्व चुनें, जिसे एक धुरी कहा जाता है , सरणी से।
  2. सरणी को फिर से व्यवस्थित करें ताकि धुरी से कम मूल्यों वाले सभी तत्व धुरी से पहले आए, जबकि धुरी से अधिक मूल्य वाले सभी तत्व इसके बाद आते हैं (समान मान किसी भी तरह से जा सकते हैं)। इस विभाजन के बाद, धुरी अपने अंतिम स्थान पर है। इसे विभाजन ऑपरेशन कहा जाता है।
  3. उपरोक्त चरणों को छोटे मानों के साथ तत्वों के उप-सरणी में और अलग-अलग मानों के साथ तत्वों के उप-सरणी में अलग से लागू करें।

नियम

नियम सरल हैं:

  • अपनी पसंद की प्रोग्रामिंग भाषा में एक संख्यात्मक क्विकसर्ट लागू करें।
  • धुरी को यादृच्छिक पर या तीन (1, अंतिम, और मध्य तत्व) के माध्यिका के साथ चुना जाना चाहिए ।
  • आपका कार्यक्रम एक पूर्ण कार्यक्रम या फ़ंक्शन हो सकता है।
  • आप एसटीडीआईएन, कमांड लाइन आर्ग्स, या फ़ंक्शन मापदंडों का उपयोग करके इनपुट प्राप्त कर सकते हैं। यदि स्ट्रिंग इनपुट का उपयोग किया जाता है, तो इनपुट अलग हो जाता है।
  • इनपुट में दशमलव और नकारात्मक मान हो सकते हैं। हालांकि, कोई डुप्लिकेट नहीं होगा।
  • आप STDOUT में या फ़ंक्शन से लौटकर आउटपुट कर सकते हैं।
  • कोई अंतर्निहित छँटाई (या संबंधित छँटाई) कार्य या मानक कमियां।
  • सूची एक मनमानी लंबाई हो सकती है।

बोनस # 1: सूची या लंबाई की उप-सूची <= 5 पर, चीजों को थोड़ा गति देने के लिए सम्मिलन प्रकार का उपयोग करें । इनाम: -15%।

बोनस # 2: यदि आपकी भाषा संक्षिप्तता का समर्थन करती है, तो सूची को समानांतर में सॉर्ट करें। यदि आप उप-सूचियों पर प्रविष्टि प्रकार का उपयोग कर रहे हैं, तो अंतिम प्रविष्टि प्रकार को समानांतर में होने की आवश्यकता नहीं है। थ्रेड पूल / थ्रेड शेड्यूलिंग में निर्मित की अनुमति है। इनाम: -15%।

नोट: तीन का मध्यस्थ कुछ लोगों को भ्रमित कर रहा था, इसलिए यहाँ एक स्पष्टीकरण है, (फिर से) शिष्टाचार:

धुरी के लिए विभाजन के पहले, मध्य और अंतिम तत्व के मध्य को चुनना

स्कोरिंग

यह । बेस स्कोर बाइट्स में है। यदि आपको एक बोनस मिला है, तो उस संख्या से 15% की छूट लें। यदि आप दोनों मिल गए, तो 30% की छूट लें। यह वास्तव में एक बिक्री पिच की तरह लग रहा है।

यह समग्र उत्तर को खोजने के बारे में नहीं है, बल्कि प्रत्येक भाषा में सबसे छोटा है।

और अब, लीडरबोर्ड स्निपेट की एक बेशर्म कॉपी।

लीडरबोर्ड

इस पोस्ट के निचले हिस्से में स्टैक स्निपेट उत्तर से सूची बनाता है) क) प्रति भाषा में सबसे छोटे समाधान की सूची के रूप में और बी) एक समग्र लीडरबोर्ड के रूप में।

यह सुनिश्चित करने के लिए कि आपका उत्तर दिखाई देता है, कृपया अपना उत्तर शीर्षक मार्कडाउन टेम्पलेट का उपयोग करके शीर्षक के साथ शुरू करें:

## Language Name, N bytes

जहाँ N आपके सबमिशन का आकार है। यदि आप अपने स्कोर में सुधार करते हैं, तो आप पुराने अंकों को हेडलाइन में रख सकते हैं, उनके माध्यम से स्ट्राइक करके। उदाहरण के लिए:

## Ruby, <s>104</s> <s>101</s> 96 bytes

यदि आप अपने हेडर में कई संख्याओं को शामिल करना चाहते हैं (जैसे कि आपका स्कोर दो फ़ाइलों का योग है या आप दुभाषिया ध्वज दंड को अलग से सूचीबद्ध करना चाहते हैं), तो सुनिश्चित करें कि हेडर में वास्तविक अंक अंतिम संख्या है:

## Perl, 43 + 2 (-p flag) = 45 bytes

आप भाषा के नाम को एक लिंक भी बना सकते हैं जो बाद में स्निपेट में दिखाई देगा:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


4
"धुरी को यादृच्छिक या तीन (1, अंतिम, और मध्य तत्व) के माध्यिका के साथ चुना जाना चाहिए।" इसका क्या मतलब है? आपने पहले कहा था कि केवल एक तत्व चुना जाता है।
msh210

2
@ डानिएरो स्निपेट अब तय हो गया है
डैनियल एम।

1
मंझला पसंद एल्गोरिदम एक कठिन आवश्यकता है? यह अव्यावहारिक है (जैसा कि, यह प्रदर्शन को संतुलित करता है) ऐसी भाषाओं में जो एक लिंक्ड सूची को उनके प्राथमिक सरणी प्रकार (हास्केल, एलआईएसपी) के रूप में उपयोग करते हैं और पहले से ही कम से कम एक उत्तर है जो नियम की उपेक्षा करता है।
जॉन ड्वोरक

2
सूची-आधारित भाषाओं में तीनों की यादृच्छिक धुरी और मंझला दोनों समस्याग्रस्त हैं। दोनों को सरणी में रैंडम एक्सेस की आवश्यकता होती है और एक लिंक की गई सूची के अंत तक पहुंच O (n) है। पहले तीन तत्वों के माध्य को लेना काफी हद तक एक ही तरह का काम नहीं करता है (यह भी क्योंकि आप तीन विभाजन के भीतर एक ही धुरी को पकड़ लेंगे) और केवल अच्छे कारण के लिए कोड को जटिल बनाता है।
जॉन ड्वोरक

1
एक और कारण के लिए हास्केल में रैंडम पिवट समस्याग्रस्त है, भी - एक बार जब आप पासा रोल करना शुरू करते हैं, तो आप अब एक फ़ंक्शन नहीं लिख रहे हैं। आप एक I / O क्रिया को परिभाषित कर रहे हैं जो एक सरणी पैदा करता है। आप एक ऐसे फ़ंक्शन को परिभाषित कर सकते हैं जो तर्क के रूप में एक आरएनजी राज्य लेता है, लेकिन यह बहुत अच्छा नहीं है।
जॉन ड्वोरक

जवाबों:


10

सी ++, 440.3 405 388 बाइट्स

518 बाइट्स - प्रविष्टि सॉर्ट = 440.3 बाइट्स के लिए 15% बोनस

477 बाइट्स - प्रविष्टि सॉर्ट = 405.45 बाइट्स के लिए 15% बोनस

474 बाइट्स - प्रविष्टि सॉर्ट = 402.9 बाइट्स के लिए 15% बोनस

456 bytes - 15% bonus for insertion sort = 387.6 bytes

3 बाइट्स (2 वास्तव में) बचाने के लिए @Luke को धन्यवाद।

18 (15 वास्तव में) बाइट को बचाने के लिए @ डौथोमास को धन्यवाद।

ध्यान दें कि मैं यहां नया हूं और यह मेरी पहली पोस्ट है।

यह एक .h(शीर्ष लेख) फ़ाइल है।

संपीड़ित कोड:

#include<iostream>
#include<ctime>
#include<cstdlib>
void s(int a[],int i,int j){int t=a[i];a[i]=a[j];a[j]=t;}int z(int a[],int b,int e){int p=a[(rand()%(e-b+1))+b];b--;while(b<e){do{b++;}while(a[b]<p);do{e--;}while(a[e]>p);if(b<e){s(a, b, e)}}return b;}void q(int a[],int b,int e){if(e-b<=5){for(int i=b;i<e;i++){for(int j=i;j>0;j--){if(a[j]<a[j-1]){s(a,j,j-1);}else{break;}}}return;}int x=z(a,b,e);q(a,b,x);q(a,x,e);}void q(int a[],int l){q(a,0,l);}

पूर्ण कोड:

#include <iostream>
#include <ctime>
#include <cstdlib>

void swapElements(int toSort[], int i, int j) {
    int temp = toSort[i];
    toSort[i] = toSort[j];
    toSort[j] = temp;
}

int partitionElements(int toSort[], int beginPtr, int endPtr)
{
    int pivot = toSort[(rand() % endPtr - beginPtr + 1) + beginPtr];
    beginPtr--;
    while (beginPtr < endPtr) {
        do {
            beginPtr++;
        } while (toSort[beginPtr] < pivot);
        do {
            endPtr--;
        } while (toSort[endPtr] > pivot);
        if (beginPtr < endPtr) {
            // Make sure they haven't crossed yet
            swapElements(toSort, beginPtr, endPtr);
        }
    }
    return beginPtr;
}

void quickSort(int toSort[], int beginPtr, int endPtr)
{
    if (endPtr - beginPtr <= 5) { // Less than 5: insertion sort
        for (int i = beginPtr; i < endPtr; i++) {
            for (int j = i; j > 0; j--) {
                if (toSort[j] < toSort[j - 1]) {
                    swapElements(toSort, j, j - 1);
                } else {
                    break;
                }
            }
        }
        return;
    }
    int splitIndex = partitionElements(toSort, beginPtr, endPtr);
    quickSort(toSort, beginPtr, splitIndex );
    quickSort(toSort, splitIndex, endPtr);
}

void quickSort(int toSort[], int length)
{
    quickSort(toSort, 0, length);
}

5
आप अंतिम फ़ंक्शन कॉल में क्विकॉर्ट और रिक्त स्थान हटाने के बजाय एकल अक्षर नाम का उपयोग करके 10 बाइट्स बचा सकते हैं। और मुझे यकीन है कि आप बोनस से बचने के लिए एक बेहतर स्कोर प्राप्त कर सकते हैं (15% पर्याप्त नहीं है)
edc65

1
आप एकल तारांकन द्वारा तर्कों के वर्ग कोष्ठक की जगह एक और 5 बाइट्स बचा सकते हैं। कुछ मैक्रो मैजिक कुछ और बाइट्स को काट सकते हैं, मुझे लगता है।
Cadaniluk

2
आप के बाद एक जगह की जरूरत नहीं है #include
ल्यूक

कॉल को हटाकर 34 बाइट्स से छुटकारा पाएं srand(time(NULL));आपको अभी भी छद्म यादृच्छिक संख्याएँ मिलेंगी rand()
दुओथोमस

9

एपीएल, 49 42 बाइट्स

{1≥⍴⍵:⍵⋄(∇⍵/⍨⍵<p),(⍵/⍨⍵=p),∇⍵/⍨⍵>p←⍵[?⍴⍵]}

यह एक अनाम पुनरावर्ती मोनाडिक फ़ंक्शन बनाता है जो दाईं ओर एक सरणी को स्वीकार करता है। यह बोनस के लिए योग्य नहीं है।

स्पष्टीकरण:

{1≥⍴⍵:⍵⋄                                     ⍝ If length(⍵) ≤ 1, return ⍵
                                  p←⍵[?⍴⍵]}  ⍝ Choose a random pivot
                           ∇⍵/⍨⍵>            ⍝ Recurse on >p
                  (⍵/⍨⍵=p),                  ⍝ Concatenate with =p
        (∇⍵/⍨⍵<p),                           ⍝ Recurse on <p

इसे ऑनलाइन आज़माएं

एक मुद्दा (8 बाइट्स की कीमत पर) मारिनस के लिए धन्यवाद और थॉमस कावा की बदौलत 7 बाइट्स बचाए!


प्रश्न निर्दिष्ट करता है कि कोई डुप्लिकेट नहीं होगा। (पता नहीं मुझे यह देखने में इतनी देर कैसे
लगी

5

सी ++ 17, 254 199 195 बाइट्स

#include<vector>
#include<cstdlib>
#define P push_back(y)
using V=std::vector<int>;V q(V a){int p=a.size();if(p<2)return a;p=rand()%p;V l,r;for(y:a)(y<a[p]?l:r).P;l=q(l);for(y:q(r))l.P;return l;}

व्हॉट्सएप के साथ:

V q(V a) {
    int p = a.size();

    if (p < 2)
        return a;

    p = rand() % p;
    V l,r;

    for (y : a)
        (y < a[p] ? l : r).P;

    l=q(l);

    for (y : q(r))
        l.P;

    return l;
}

सरंड (समय (NULL)) की कोई आवश्यकता नहीं है। मिटाए जाने की कोई आवश्यकता नहीं है, बस मान को विभाजित होने दें, फिर 'if (a.empty ()) को' if '(a.size () <2)' में बदलें और 'lP (x)' निकालें।
क्रिस जेफरसन

मिटा को खत्म करने से मुझे बहुत सारे बाइट्स बचाने की अनुमति मिली । धन्यवाद!
लिन 11

एक अन्य छोटे से एक: 'r = q (r)' असाइन करने की आवश्यकता नहीं है, बस '(y: q (r))' के लिए उपयोग करें, लेकिन यह सब मैं देख सकता हूँ!
क्रिस जेफरसन

जिज्ञासा से बाहर: विशेष रूप से यहाँ C ++ 17 कहाँ है?
kirbyfan64sos

1
for (y : a)अन्यथा की आवश्यकता होगी for (auto y : a)या for (int y : a)। (वास्तव में, clang++इसे C ++ 1z एक्सटेंशन कहते हैं , लेकिन यह वास्तव में C ++ 17 नहीं लगता है; मुझे नहीं पता और इसे देखने के लिए रात में बहुत देर हो चुकी है।)
लिन

4

पायथ, 25 बाइट्स

L?tbsyMa_,]JObf<TJbf>TJbb

यह एक फ़ंक्शन को परिभाषित करता है y, जो इनपुट के रूप में संख्याओं की एक सूची लेता है।

इसे ऑनलाइन आज़माएँ: प्रदर्शन

व्याख्या

L?tbsyMa_,]JObf<TJbf>TJbb
L                          define function y(b), that returns: 
 ?tb                         if t[1:] (if the list has more than one element):
            Ob                 choose a random element of b
           J                   save it in J
          ]                    put J in a list
         ,    f<TJb            create a pair, that contains ^ and a list of 
                               all numbers smaller than J: [[J], [smaller than J]] 
        _                      reverse this list: [[smaller than J], [J]]
       a           f>TJb       append a list with all elements bigger than J: 
                               [[smaller than J], [J], [bigger than J]]
     yM                        call y recursively for each sublist
    s                          combine the results and return it
                        b    else: simply return b

पायथ, 21 बाइट्स (शायद अमान्य)

मैं "समूह-दर" विधि का उपयोग करता हूं, जो आंतरिक रूप से एक प्रकार का उपयोग करता है। मैं इसका उपयोग मूल सूची को तीन उपखंडों में विभाजित करने के लिए करता हूं (सभी तत्व धुरी से छोटे हैं, धुरी और धुरी से बड़े सभी तत्व हैं)। "समूह-दर" में इस प्रकार के बिना, यह इन 3 सूचियों को एक अलग क्रम में वापस कर सकता है।

जैसा कि कहा गया है, यह संभवतः अमान्य है। फिर भी मैं इसे यहां रखूंगा, क्योंकि यह एक दिलचस्प समाधान है।

L?tb&]JObsyM.g._-kJbb

इसे ऑनलाइन आज़माएँ: प्रदर्शन

व्याख्या

L?tb&]JObsyM.g._-kJbb
L                      def y(b): return
 ?tb                     if t[1:] (if the list has more than one element):
       Ob                  choose a random element of b
      J                    save it in J
    &]                     put it in an array and call "and" 
                           (hack which allows to call 2 functions in one statement)

            .g     b       group the elements in b by:
              ._-kJ           the sign of (k - J)
                           this generates three lists
                             - all the elements smaller than J
                             - J
                             - all the elements bigger than J
          yM               call y recursively for all three lists
         s                 and combine them
                    b    else: return b

3

> <> (मछली), 313 309 बाइट्स

!;00l[l2-[b1.
>:0)?v~$:@&vl2,$:&${:}$
^-1@{< ]]. >055[3[5b.
?v~~@~ v:}@:}@:}:}@:}@}}}(}(}({{:@=
.>=$~?$>~]]
.001-}}d6.{$}1+}d6
?v:{:}@{(?v08.}:01-=
 >{$~~{09.>95.v-1@{<   v-1}$<
.:@}:@{=${::&@>:0)?^~}&>:0)?^~+}d6
 1-:0a.{{$&l&1+-: >:0)?v~:1)?!v62fb.
>:0)?v~:}:1)?v~69.^@{-1<>.!]]~<
^@{-1<:}@@73.>69@@:3+[{[b1.

मुझे लिखने में बहुत समय लगा। आप इसे यहां आज़मा सकते हैं , बस उस सूची को डाल दें, जिसे प्रोग्राम को चलाने से पहले, अल्पविराम से अलग किया गया है, अल्पविराम से अलग किया गया है।

यह काम किस प्रकार करता है

प्रारंभिक स्टैक में प्रोग्राम पहले, मध्य और अंतिम तत्व को पकड़ लेता है और इन तीनों के माध्य की गणना करता है।
यह तब स्टैक को इसमें बदलता है:

[सूची 1] तत्व [सूची 2]

जहाँ सूची १ में सब कुछ छोटा या तत्व के बराबर है और सूची २ में सब कुछ बड़ा है।
यह पुन: सूची 1 पर इस प्रक्रिया को दोहराता है और सूची 2 को पूरी सूची में क्रमबद्ध नहीं करता है।


2

सीजेएम, 40 बाइट्स

{_1>{_mR:P-PaL@{_P<{+}{@\+\}?}/J\J+}&}:J

यह एक नामित फ़ंक्शन है जो स्टैक पर एक सरणी की अपेक्षा करता है और बदले में एक को धक्का देता है।

CJam दुभाषिया में इसे ऑनलाइन आज़माएं ।

उपरोक्त कोड संभव के रूप में कल्पना का अनुसरण करता है। यदि इसकी आवश्यकता नहीं है, तो 12 बाइट्स बचाए जा सकते हैं:

{_1>{_mR:P;_{P<},J_@^J+}&}:J

2

पायथन 3, 123 , 122।

हारून के लिए 1 बाइट धन्यवाद।

यह पहली बार है जब मैंने वास्तव में एक छँटाई एल्गोरिथ्म लिखने के लिए परेशान किया है। यह वास्तव में थोड़ा आसान है जितना मैंने सोचा था कि यह होगा।

from random import*
def q(s):
 if len(s)<2:return s
 p=choice(s);return q([d for d in s if d<=p])+q([d for d in s if d>p])

Ungolfed:

from random import choice
def quick_sort(seq):
    if len(seq) < 2:
        return seq
    low = []
    high = []
    pivot = choice(seq)
    for digit in seq:
        if digit > pivot:
            high += [digit]
        else:
            low += [digit]
    return quick_sort(low) + quick_sort(high)

ऐसा लगता है कि <=तुलना के कारण यह काम नहीं कर सकता है - यह गारंटी नहीं देता है कि pयह सही जगह पर है, आपको संभवतः इसे एक विशेष असमानता में बदलने की जरूरत है, और pस्वतंत्र रूप से बीच में जोड़ें (मैंने परीक्षण नहीं किया है / कर सकते हैं 't परीक्षण कोड)।
विजुअलमेल

@VisualMelon मैंने इसे विभिन्न मामलों के एक समूह के साथ परीक्षण किया और कभी भी गलत परिणाम नहीं मिला, लेकिन अगर आप इसे तोड़ने वाले एक परीक्षण के मामले को ढूंढ सकते हैं, तो मुझे बताएं। इसके अलावा, यह डुप्लिकेट के साथ काम नहीं कर सकता है, लेकिन चुनौती निर्दिष्ट करती है कि डुप्लिकेट नहीं होंगे।
मॉर्गन थ्रैप

मैंने सोचा था कि [2, 1, 3]यह 1/3 बार टूट जाएगा, क्योंकि जब यह धुरी 2 का चयन करता है, तो इसकी निम्न सूची होगी [2, 1]- मुझे खेद है कि मैं अभी इसका परीक्षण नहीं कर सकता।
विजुअलमेल

@VisualMelon ठीक है, यकीन है, लेकिन यह फिर से पुन: व्यवस्थित करता है।
मॉर्गन थ्रैप

आह, माफ करना, पूरी तरह से याद किया, नहीं कि मैं कैसे एक क्विकॉर्ट लागू होने की उम्मीद करूंगा - मुझे भ्रमित करने के लिए एक upvote है
विज़ुअलमेल

2

जावास्क्रिप्ट (ES2015), 112

q=l=>{let p=l[(Math.random()*l.length)|0];return l.length<2?l:q(l.filter(x=>x<=p)).concat(q(l.filter(x=>x>p)));}

व्याख्या

//Define lambda function q for quicksort
q=l=>{

    //Evaluate the pivot
    let p=l[(Math.random()*l.length)|0];

    //return the list if the length is less than 2
    return l.length < 2 ? l:

    //else return the sorted list of the elements less or equal than 
      the pivot concatenated with the sorted list of the elements 
      greater than the pivot
    q(l.filter(x=>x<=p)).concat(q(l.filter(x=>x>p)));
}

ES6 शायद इसे छोटा कर सकता है।
निसा

1

माणिक, 87 60 बाइट्स

q=->a,p=a.sample{a[1]?(l,r=a.partition{|e|e<p};q[l]+q[r]):a}

Ungolfed:

def quicksort(a, pivot=a.sample)
  if a.size > 1
    l,r = a.partition { |e| e < pivot}
    quicksort(l) + quicksort(r)
  else
    a
  end
end

परीक्षा:

q[[9, 18, 8, 5, 13, 20, 7, 14, 16, 15, 10, 11, 2, 4, 3, 1, 12, 17, 6, 19]]
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

1

ऑक्टेव, 76 75 बाइट्स

function u=q(u)n=numel(u);if n>1 k=u(randi(n));u=[q(u(u<k)),q(u(u>=k))];end

बहु-पंक्ति संस्करण:

function u=q(u) 
   n=numel(u);
   if n>1 
      k=u(randi(n));
      u=[q(u(u<k)),q(u(u>=k))];
   end

1

जूलिया, 83 बाइट्स

Q(x)=endof(x)<2?x:(p=rand(x);[Q((f=filter)(i->i<p,x));f(i->i==p,x);Q(f(i->i>p,x))])

यह एक पुनरावर्ती फ़ंक्शन बनाता है Qजो किसी सरणी को स्वीकार करता है और एक सरणी देता है। यह सशर्त रूप से सम्मिलन प्रकार का उपयोग नहीं करता है, इसलिए कोई बोनस लागू नहीं होता है।

Ungolfed:

function Q(x::AbstractArray)
    if endof(x)  1
        # Return on empty or 1-element arrays
        x
    else
        # Select a random pivot
        p = rand(x)

        # Return the function applied to the elements less than
        # the pivot concatenated with those equal to the pivot
        # and the function applied to those greater than the pivot
        [Q(filter(i -> i < p, x));
         filter(i -> i == p, x);
         Q(filter(i -> i > p, x))]
    end
end

एक मुद्दा फिक्स्ड और ग्लेन हे के लिए कुछ बाइट्स को बचाया!


दोहराने के तत्वों के नुकसान के साथ संभावित मुद्दे (जो आपके कोड में पहले से मौजूद हैं) एक तरफ, आप कुछ बाइट्स को सहेज कर रख सकते हैं fजब आप पहली बार उपयोग करते हैं filter, और endofइसके बजाय का उपयोग करके lengthQ(x)=endof(x)<2?x:(p=rand(x);[Q((f=filter)(i->i<p,x));p;Q(f(i->i>p,x))])
ग्लेन ओ

@GlenO सुझाव के लिए धन्यवाद। मैंने इसे लागू किया है और बार-बार तत्वों के साथ समस्या को ठीक किया है।
एलेक्स ए।

मैंने कहा कि यह एक मुद्दा हो सकता है, लेकिन मैंने स्पष्टीकरण के लिए प्रश्न पोस्टर पूछा, और "इनपुट में दशमलव और नकारात्मक मान हो सकते हैं। हालांकि, कोई डुप्लिकेट नहीं होगा"
Glen O

1

आर, 78 बाइट्स

Q=function(x)if(length(x)>1)c(Q(x[x<(p=sample(x,1))]),x[x==p],Q(x[x>p]))else x

यह एक पुनरावर्ती कार्य बनाता है Qजो एक वेक्टर को स्वीकार करता है और एक वेक्टर लौटाता है। यह सशर्त रूप से सम्मिलन प्रकार लागू नहीं करता है, इसलिए कोई बोनस नहीं।

Ungolfed:

Q <- function(x) {
    # Check length
    if (length(x) > 1) {
        # Select a random pivot
        p <- sample(x, 1)

        # Recurse on the subarrays consisting of
        # elements greater than and less than p,
        # concatenate with those equal to p
        c(Q(x[x < p]), x[x == p], Q(x[x > p]))
    } else {
        x
    }
}

इसे ऑनलाइन आज़माएं

Flodel के लिए धन्यवाद 4 बाइट्स सहेजे गए!


आप लंबाई की तुलना में "> 1" गिराकर कुछ बाइट्स को बंद कर सकते हैं। यह स्पष्ट रूप से इसकी तुलना 0 से करता है, लेकिन पुनरावृत्ति की एक अतिरिक्त परत कोई समस्या नहीं है,
Miff

@ अपने इनपुट के लिए धन्यवाद, लेकिन मैंने कोशिश की है और यह मेरे लिए अपेक्षित परिणाम नहीं देता है।
एलेक्स ए।

1

के, 41 बाइट्स

s:{$[#x;(s@x@&x<p),p,s@x@&x>p:x@*1?#x;x]}

ले लो, कि एपीएल !!! बोनस में से कोई भी नहीं करता है।


1

हास्केल, 137136 बाइट्स

f=filter
m a b c=max(min a b)(min(max a b)c)
q[]=[]
q l=let{n=m(head l)(head$drop(length l`div`2)l)(last l)}in(q$f(<n)l)++(n:(q$f(>n)l))

विस्तारित संस्करण और फ़ंक्शन नाम और कुछ मध्यवर्ती परिणाम के साथ ungolfed संस्करण यहां है:

median a b c = max (min a b) (min (max a b) c)
quicksort [] = []
quicksort l = let mid = median (head l) (middle l) (last l)
                  lesser = filter (< mid) l
                  greater = filter (> mid) l
                  middle l = head $ drop (length l `div` 2) l
              in (quicksort lesser) ++ (mid : (quicksort greater))

मैं इस तथ्य का लाभ उठा रहा हूं कि दो सख्त तुलनाओं का उपयोग करने के लिए कोई डुप्लिकेट नहीं है। मुझे यह देखना होगा कि Data.List.partitionक्या चीजें छोटी नहीं होती हैं, यहां तक ​​कि यह मानते हुए कि मुझे एक आयात विवरण जोड़ना होगा। मैं सम्मिलन सॉर्ट बोनस नहीं ले रहा हूं क्योंकि मैं Data.List.insertएक छँटाई से संबंधित फ़ंक्शन के रूप में मानता हूं - इस प्रकार निषिद्ध है - और यदि इसका उपयोग नहीं किया जाता है, तो सम्मिलन सॉर्ट को जोड़ने से कोड 246 बाइट्स, 209.1 को बोनस के साथ धक्का देता है, इसलिए यह इसके लायक नहीं है।

संपादित करें: उपयोग करने के लिए एक उपनाम बनाने के लिए उनके सुझाव के लिए RobAu का धन्यवाद f=filter। यह केवल एक बाइट बचा सकता है लेकिन सब कुछ मदद करता है।


1
f=filterकुछ बाइट्स शेव कर सकते हैं।
रोबू

हो सकता है कि आप दो अनावश्यक q$f(>n)lऔर q$f(<n)lकॉल को संभालने के लिए एक फ़ंक्शन बनाकर कुछ बाइट्स दाढ़ी कर सकते हैं?
साइओस

1

Tcl, 138 बाइट्स

proc q v {if {$v eq {}} return
lassign {} a b
foreach x [lassign $v p] {if {$x<$p} {lappend a $x} {lappend b $x}}
concat [q $a] $p [q $b]}

यह एक अत्यधिक मानक क्विकॉर्ट है।

धुरी बस प्रत्येक सबरेरे का पहला तत्व है (मैं तर्क देता हूं कि यह एक यादृच्छिक संख्या है। https://xkcd.com/n1.1 )

यह स्मृति उपयोग के मामले में विशेष रूप से कुशल नहीं है, हालांकि इसे tailcallदूसरी पुनरावृत्ति और n <1 तत्वों के आधार मामले के साथ कुछ सुधार किया जा सकता है ।

यहाँ पठनीय संस्करण है:

proc quicksort xs {
  if {![llength $xs]} return
  set lhs [list]
  set rhs [list]
  foreach x [lassign $xs pivot] {
    if {$x < $pivot} \
      then {lappend lhs $x} \
      else {lappend rhs $x}
  }
  concat [quicksort $lhs] $pivot [quicksort $rhs]
}

सभी इनपुट पर काम करता है और डुप्लिकेट की अनुमति देता है। ओह, यह भी स्थिर है । आप इसे कुछ सरल से परख सकते हैं, जैसे:

while 1 {
  puts -nonewline {xs? }
  flush stdout
  gets stdin xs
  if {$xs eq {}} exit
  puts [q $xs]    ;# or [quicksort $xs]
  puts {}
}

का आनंद लें! : ओ)


आप की जगह बाइट्स बचा सकता foreachद्वारा lmap
sergiol

1

जावास्क्रिप्ट (ईएस 6), 191

Q=(a,l=0,h=a.length-1)=>l<h&&(p=((a,i,j,p=a[i+(0|Math.random()*(j-i))])=>{for(--i,++j;;[a[i],a[j]]=[a[j],a[i]]){while(a[--j]>p);while(a[++i]<p);if(i>=j)return j}})(a,l,h),Q(a,l,p),Q(a,p+1,h))

// More readable
U=(a,l=0,h=a.length-1)=>l<h && 
  (p=( // start of partition function
    (a,i,j,p=a[i+(0|Math.random()*(j-i))])=>
    {
      for(--i,++j;;[a[i],a[j]]=[a[j],a[i]])
      {
        while(a[--j]>p);
        while(a[++i]<p);
        if(i>=j)return j
      }
    } // end of partition function
  )(a,l,h),U(a,l,p),U(a,p+1,h))

// This is the shortest insertion sort that I could code, it's 72 bytes
// The bonus is worth  ~30 bytes - so no bonus
I=a=>{for(i=0;++i<a.length;a[j]=x)for(x=a[j=i];j&&a[j-1]>x;)a[j]=a[--j]}


// TEST
z=Array(10000).fill().map(_=>Math.random()*10000|0)

Q(z)

O.innerHTML=z.join(' ')
<div id=O></div>


1

सीलोन (जेवीएम केवल), 183 170

कोई बोनस लागू नहीं होता।

import ceylon.math.float{r=random}{Float*}q({Float*}l)=>if(exists p=l.getFromFirst((r()*l.size).integer))then q(l.filter((e)=>e<p)).chain{p,*q(l.filter((e)=>p<e))}else[];

ऐसा लगता है कि सीलोन में एक यादृच्छिक संख्या का उत्पादन करने के लिए कोई क्रॉस-प्लेटफ़ॉर्म तरीका नहीं है, इसलिए यह केवल जेवीएम है। (अंत में मेरे पास एक गैर-यादृच्छिक संस्करण है जो JS में भी काम करता है, और छोटा है।)

यह एक फ़ंक्शन को परिभाषित करता है जो फ़्लोटर्स की पुनरावृत्ति लेता है, और इसके एक सॉर्ट किए गए संस्करण को लौटाता है।

import ceylon.math.float {
    r=random
}

{Float*} q({Float*} l) {
    if (exists p = l.getFromFirst((r() * l.size).integer)) {
        return q(l.filter((e) => e < p)).chain { p, *q(l.filter((e) => p < e)) };
    } else {
        return [];
    }
}

यदि (विनिर्देश के विरुद्ध) डुप्लिकेट प्रविष्टियाँ पास की जाती हैं, तो उन्हें फ़िल्टर कर दिया जाएगा।

यह 183 बाइट्स हैं: import ceylon.math.float{r=random}{Float*}q({Float*}l){if(exists p=l.getFromFirst((r()*l.size).integer)){return q(l.filter((e)=>e<p)).chain{p,*q(l.filter((e)=>p<e))};}else{return[];}}

हम नई (सीलोन 1.2) ifअभिव्यक्ति का उपयोग करके थोड़ा सुधार कर सकते हैं :

import ceylon.math.float {
    r=random
}

{Float*} q({Float*} l) =>
        if (exists p = l.getFromFirst((r() * l.size).integer))
        then q(l.filter((e) => e < p)).chain { p, *q(l.filter((e) => p < e)) }
        else [];

यह 170 बाइट्स है: import ceylon.math.float{r=random}{Float*}q({Float*}l)=>if(exists p=l.getFromFirst((r()*l.size).integer))then q(l.filter((e)=>e<p)).chain{p,*q(l.filter((e)=>p<e))}else[];


यहाँ एक गैर-यादृच्छिक संस्करण है:

{Float*} r({Float*} l) =>
        if (exists p = l.first)
        then r(l.filter((e) => e < p)).chain { p, *r(l.filter((e) => p < e)) }
        else [];

रिक्त स्थान के बिना यह 107 बाइट होगा: {Float*}r({Float*}l)=>if(exists p=l.first)then r(l.filter((e)=>e<p)).chain{p,*r(l.filter((e)=>p<e))}else[];


0

AutoIt , 320.45 304.3 बाइट्स

यह बहुत तेज़ है (वैसे भी AutoIt के लिए)। प्रविष्टि सॉर्ट बोनस के लिए योग्य है। अंतिम गोल्फिंग के बाद स्पष्टीकरण जोड़ेंगे।

इनपुट है q(Array, StartingElement, EndingElement)

Func q(ByRef $1,$2,$3)
$5=$3
$L=$2
$6=$1[($2+$3)/2]
If $3-$2<6 Then
For $i=$2+1 To $3
$4=$1[$i]
For $j=$i-1 To $2 Step -1
$5=$1[$j]
ExitLoop $4>=$5
$1[$j+1]=$5
Next
$1[$j+1]=$4
Next
Else
Do
While $1[$L]<$6
$L+=1
WEnd
While $1[$5]>$6
$5-=1
WEnd
ContinueLoop $L>$5
$4=$1[$L]
$1[$L]=$1[$5]
$1[$5]=$4
$L+=1
$5-=1
Until $L>$5
q($1,$2,$5)
q($1,$L,$3)
EndIf
EndFunc

रैंडम परीक्षण इनपुट + आउटपुट:

862, 543, 765, 577, 325, 664, 503, 524, 192, 904, 143, 483, 146, 794, 201, 511, 199, 876, 918, 416
143, 146, 192, 199, 201, 325, 416, 483, 503, 511, 524, 543, 577, 664, 765, 794, 862, 876, 904, 918

दिलचस्प है, पहले कभी AutoIt के बारे में नहीं सुना
डैनियल एम।

0

जावा, 346 बाइट्स

407 bytes - 15% bonus for insertion sort = 345.95 bytes

संपीड़ित कोड:

class z{Random r=new Random();void q(int[] a){q(a,0,a.length);}void q(int[] a,int b,int e){if(e-b<6){for(int i=b;i<e;i++){for(int j=i;j>0&a[j]<a[j-1];j--){s(a,j,j-1);}}return;}int s=p(a,b,e);q(a,b,s);q(a,s,e);}int p(int[] a,int b,int e){int p=a[r.nextInt(e-b)+b--];while(b<e){do{b++;}while(a[b]<p);do{e--;}while(a[e]>p);if(b<e){s(a,b,e);}}return b;}void s(int[] a,int b,int e){int t=a[b];a[b]=a[e];a[e]=t;}}

पूर्ण कोड:

public class QuickSort {

    private static final Random RANDOM = new Random();

    public static void quickSort(int[] array) {
        quickSort(array, 0, array.length);
    }

    private static void quickSort(int[] array, int begin, int end) {
        if (end - begin <= 5) {
            for (int i = begin; i < end; i++) {
                for (int j = i; j > 0 && array[j] < array[j - 1]; j--) {
                    swap(array, j, j - 1);
                }
            }
            return;
        }
        int splitIndex = partition(array, begin, end);
        quickSort(array, begin, splitIndex);
        quickSort(array, splitIndex, end);
    }

    private static int partition(int[] array, int begin, int end) {
        int pivot = array[RANDOM.nextInt(end - begin) + begin];
        begin--;
        while (begin < end) {
            do {
                begin++;
            } while (array[begin] < pivot);
            do {
                end--;
            } while (array[end] > pivot);
            if (begin < end) {
                // Make sure they haven't crossed yet
                swap(array, begin, end);
            }
        }
        return begin;
    }

    private static void swap(int[] array, int begin, int end) {
        int temp = array[begin];
        array[begin] = array[end];
        array[end] = temp;
    }

}

युगल में सुधार: 1. int [] और विधि हेडर के बीच रिक्त स्थान से छुटकारा पाएं। 2. एक लूप में एक चर तक पहुँचने के लिए एक लूप में वृद्धि या गिरावट करें। 3. नए इंट के बजाय बाइट्स को बचाने के लिए एक क्लास इंट (या एक युगल) बनाएं। 4. Math.random () का उपयोग करना और रैंडम ऑब्जेक्ट बनाने से छोटा हो सकता है।
ब्लू

0

गणितज्ञ, 93 90 बाइट्स

If[Length@#>1,pv=RandomChoice@#;Join[qs2[#~Select~(#<pv&)],{pv},qs2[#~Select~(#>pv&)]],#]&

नो बोनस, अभी तक प्रविष्टि सॉर्ट करने का एक न्यूनतम तरीका नहीं मिला है। जब मैं हाल ही में सी ++ सीख रहा था, तो मैंने यहां विभिन्न छंटाई एल्गोरिदम की तुलना की ।


0

पायथन 2, 120 बाइट्स

def p(a):
 if[]==a[1:]:return a
 b,c,m=[],[],__import__("random").choice(a)
 for x in a:[b,c][x>m]+=[x];return p(b)+p(c)

if[]==a[1:]वास्तव में लंबे समय के रूप में है, if len(a)>2लेकिन अधिक गोल्फ दिखता है।


0

लुआ, 242 बाइट्स

function f(t,p)if(#t>0)then local P,l,r,i=math.random(#t),{},{},table.insert p=t[P]for k,v in ipairs(t)do if(k~=P)then i(v<p and l or r,v)end end t={}for k,v in pairs(f(l))do i(t,v)end i(t,p)for k,v in pairs(f(r))do i(t,v)end end return t end

अधूरा और स्पष्टीकरण

function f(t,p)                                             # Assign 'p' here, which saves two bytes, because we can't assign it to t[P] IN the local group.
    if(#t>0)then                                            # Just return 0 length lists...
        local P,l,r,i=math.random(#t),{},{},table.insert    # Using local here actually makes the a,b=1,2 method more efficient here. Which is unnormal for Lua
        p = t[P]                                            # P is the index of the pivot, p is the value of the pivot, l and r are the sub-lists around the pivot, and i is table.insert to save bytes.
        for k,v in ipairs(t) do                             # We use a completely random pivot, because it's cheaper on the bytes.
            if(k~=P)then                                    # Avoid 'sorting' the pivot.
                i(v<p and l or r,v)                         # If the value is less than the pivot value, push it to the left list, otherwise, push it to the right list.
            end                                             #
        end                                                 #
        t = {}                                              # We can re-use t here, because we don't need it anymore, and it's already a local value. Saving bytes!
        for k,v in pairs(f(l)) do                           # Quick sort the left list, then append it to the new output list.
            i(t,v)                                          #
        end                                                 #
        i(t,p)                                              # Append the pivot value.
        for k,v in pairs(f(r)) do                           # Ditto the right list.
            i(t,v)                                          #
        end                                                 #
    end                                                     #
    return t                                                # Return...
end                                                         #

0

रैकेट 121 बाइट्स

(λ(l)(if(null? l)l(let((h(car l))(t(cdr l)))(append(qs (filter(λ(x)(< x h))t))(list h)(qs (filter(λ(x)(>= x h))t))))))

Ungolfed (l = list, h = head (पहला तत्व), t = tail (बाकी या शेष तत्व)):

(define qs
  (λ(l)
    (if (null? l) l
        (let ((h (first l))
              (t (rest  l)))
          (append (qs (filter (λ(x) (< x h) ) t))
                  (list h) 
                  (qs (filter (λ(x) (>= x h)) t))  )))))

परिक्षण:

(qs (list 5 8 6 8 9 1 2 4 9 3 5 7 2 5))

आउटपुट:

'(1 2 2 3 4 5 5 5 6 7 8 8 9 9)

0

जाप , 23 बाइट्स

प्रत्येक बोनस को कुल स्कोर में तीन बाइट्स या कम भुगतान करने की आवश्यकता होगी, इसलिए मैंने कोई बोनस नहीं लिया।

Z=Uö;Ê<2?UUf<Z)cßUf¨Z
Z=Uö;                   // Take a random element from the input for partitioning.
     Ê<2                // If the input is shorter than two elements,
        ?U              // return it.
          :             // Otherwise
           ß      ß     // recursively run again
            Uf<Z        // with both items that are smaller than the partition
                   Uf¨Z // and those that are larger or equal,
                )c      // returning the combined result.

इसे ऑनलाइन आज़माएं!


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.