एक स्ट्रिंग inplace में शब्दों का क्रम


17

काम

  • आपको एक परस्पर स्ट्रिंग दी जाती है जो मेल खाती है [a-z]+( [a-z]+)*
  • आपको इसे स्ट्रिंग में म्यूट करना होगा जिसमें समान शब्द हैं, लेकिन रिवर्स ऑर्डर में, ताकि "हेलो वहाँ हर कोई" हर कोई "हैलो वहाँ" हो जाए।
  • आपको अतिरिक्त मेमोरी की निरंतर मात्रा से अधिक का उपयोग करने की अनुमति नहीं है (इसलिए आपके द्वारा आवंटित बफर में पूरे स्ट्रिंग या किसी भी पूरे शब्द की नकल नहीं की जाती है)।
  • कोई समय की कमी नहीं हैं। निराशाजनक रूप से अक्षम होना आपके स्कोर को नुकसान नहीं पहुंचाएगा।
  • यदि आपकी पसंद की भाषा स्ट्रिंग्स के म्यूटेशन की अनुमति नहीं देती है, तो वर्णों के सरणियाँ एक स्वीकार्य विकल्प हैं।

अपने स्कोर

  • आपका स्कोर विशुद्ध रूप से गिना जाता है कि आप स्ट्रिंग तत्वों (छोटे स्कोर सबसे अच्छे हैं) के लिए कितने वर्गीकरण हैं। यदि आप एक लाइब्रेरी फ़ंक्शन का उपयोग करते हैं जो स्ट्रिंग को लिखता है, तो इसका लेखन भी गणना करता है।
  • मान लीजिए कार्य की संख्या आप निवेश के लिए की जरूरत है रों है n (रों) । तो फिर अपने स्कोर को अधिकतम (pedantically, supremum) सभी आदानों खत्म हो गया है रों की (regex ऊपर निर्दिष्ट मिलान) एन (रों) / लंबाई (रों) । यदि आप इसकी सटीक गणना नहीं कर सकते हैं, तो आप सबसे कम ऊपरी सीमा का उपयोग कर सकते हैं जिसे आप साबित कर सकते हैं।
  • आप एक टाई तोड़ सकते हैं यदि आप यह साबित कर सकते हैं कि आपका एल्गोरिथ्म असिमोटली कम असाइनमेंट का उपयोग करता है (ऐसा तब भी हो सकता है जब आपके पास समान स्कोर हो, नीचे देखें)। यदि आप ऐसा नहीं कर सकते, तो आप यह दिखा कर टाई तोड़ सकते हैं कि आप कम अतिरिक्त मेमोरी का उपयोग करते हैं। हालांकि, पहले टाई-ब्रेक की स्थिति हमेशा पूर्वता लेती है।
  • कुछ इनपुट के लिए हर चरित्र को बदलने की आवश्यकता होती है, इसलिए 1 से कम स्कोर करना संभव नहीं है।
  • मैं स्कोर 2 के साथ एक सरल एल्गोरिथ्म के बारे में सोच सकता हूं (लेकिन मैं इसे दर्ज नहीं कर रहा हूं)।

Suprema और संबंधों पर नोट्स

  • संख्याओं के समूह का एक वर्चस्व सबसे छोटी संख्या है जो उनमें से किसी से छोटी नहीं है। यह एक सेट के अधिकतम की तरह है, सिवाय इसके कि कुछ अनंत सेट जैसे {2/3, 3/4, 4/5, 5/6, ...} में एक भी अधिकतम तत्व नहीं है, लेकिन फिर भी एक वर्चस्व होगा, इस मामले में 1।
  • यदि आप स्कोर 2 के मेरे एल्गोरिथ्म (कहते हैं) पर केवल एक निरंतर संख्या में "सेव" करने का प्रबंधन करते हैं, तो आपका स्कोर अभी भी 2 होगा, क्योंकि आप मनमाने ढंग से आपके इनपुट के बड़े होने के 2 करीब होंगे। हालाँकि, आप टाई-ब्रेक पर जीत जाते हैं यदि यह उस पर आता है।

1
मैं थोड़ा दुखी होता अगर यह सब उनकी स्मृति उपयोग पर स्कोर-ब्रेकिंग स्कोर -2 सबमिशन के लिए नीचे आता। मैं ज्यादातर इस सवाल को सोच कर पोस्ट करता था कि क्या कोई स्कोर 2 से कम स्कोर करेगा
बेन मिलवुड

1
मेरे पास कोई औपचारिक प्रमाण नहीं है, लेकिन मेरा अंतर्ज्ञान मुझे बताता है कि निरंतर-अंतरिक्ष प्रतिबंध के साथ, यह 2 से बेहतर करना असंभव है। यदि आप केवल अंतरिक्ष के लिए चर घोषणाओं को गिनते हैं, तो मैं धोखा दे सकता हूं और पुनरावर्ती कार्य कर सकता हूं। लेकिन यह केवल little-omega(1)स्टैक पर रखकर अंतरिक्ष को प्रच्छन्न करता है।
गलत

2
@bacchusbeale हाँ, लेकिन यह निरंतर अतिरिक्त मेमोरी है।
मार्टिन एंडर

4
यदि आप नियमों को कड़ाई से लागू करते हैं तो ऐसा कार्यक्रम लिखना असंभव है। स्ट्रिंग मनमानी लंबाई का हो सकता है और आपको कम से कम कुछ प्रकार के चर की आवश्यकता होगी जो एक सूचकांक को संग्रहीत करता है। इसलिए मुझे आपके स्ट्रिंग की सीमा को पार करने के लिए स्ट्रिंग को काफी लंबा करना होगा। कम से कम एक इंडेक्स को सफलतापूर्वक स्टोर करने के लिए आपकी आवश्यक मेमोरी स्ट्रिंग की लंबाई के साथ बढ़ेगी।
IchBinKeinBaum

3
@IchBinKeinBaum सही है, इस कार्य को O(1)अतिरिक्त स्थान के साथ करना असंभव है। आपको O(log n)इंडेक्स पोजीशन को स्टोर करने के लिए जगह की आवश्यकता होती है, क्योंकि k-bit पूर्णांक केवल लंबाई तक के स्ट्रिंग्स के लिए उनमें स्टोर कर सकता है 2^k। स्ट्रिंग्स की लंबाई को सीमित करना चुनौती को व्यर्थ बनाता है, क्योंकि प्रत्येक एल्गोरिथ्म को O(1)इस तरह से जगह की आवश्यकता होगी ।
डेनिस

जवाबों:


4

पायथन, स्कोर: 2 1.5 1.25

यह प्रत्यक्ष है प्राइमो के उत्तर और मेरे उत्तर के बीच संयोजन है। तो उसे भी श्रेय!

सबूत अभी भी जारी है, लेकिन यहाँ कोड के साथ खेलना है! यदि आप 1.25 से अधिक स्कोर का एक काउंटर उदाहरण पा सकते हैं (या यदि कोई बग है), तो मुझे बताएं!

वर्तमान में सबसे खराब स्थिति यह है:

आ… आ डीसीबी… सीबीडी

जहाँ प्रत्येक अक्षर "a", "b", "c", और "" (स्थान) के बिल्कुल n होते हैं , और वास्तव में दो "d" s होते हैं। स्ट्रिंग की लंबाई 4n + 2 है और असाइनमेंट की संख्या 5n + 2 है , जिससे 5/4 = 1.25 का स्कोर मिलता है ।

एल्गोरिथ्म दो चरणों में काम करता है:

  1. kऐसे खोजें string[k]और string[n-1-k]शब्द सीमाएँ हैं
  2. छोटे संशोधन के साथ string[:k]+string[n-1-k:](यानी, पहले kऔर अंतिम kवर्णों का संघटन) पर किसी भी शब्द के एल्गोरिथ्म को चलाएं ।

जहां nस्ट्रिंग की लंबाई है।

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

ऐसे मामले हैं जहां हम वास्तव में ऐसा नहीं पा सकते हैं k , उस स्थिति में, हम पूरे स्ट्रिंग पर "कोई भी शब्द उलट एल्गोरिथ्म" चलाते हैं।

कोड "कॉन्कैटनेटेड" स्ट्रिंग पर शब्द रिवर्सल एल्गोरिदम को चलाने पर इन चार मामलों को संभालने के लिए लंबा है:

  1. जब kनहीं मिला ( f_long = -2)
  2. जब string[k] != ' ' and string[n-1-k] != ' '( f_long = 0)
  3. जब string[k] != ' ' and string[n-1-k] == ' '( f_long = 1)
  4. जब string[k] == ' ' and string[n-1-k] != ' '( f_long = -1)

मुझे यकीन है कि कोड को छोटा किया जा सकता है। वर्तमान में यह लंबा है क्योंकि मेरे पास शुरुआत में पूरे एल्गोरिथ्म की स्पष्ट तस्वीर नहीं थी। मुझे यकीन है कि कोई इसे एक छोटे कोड में दर्शाने के लिए डिज़ाइन कर सकता है =)

नमूना रन (पहला मेरा है, दूसरा है प्राइमो का):

स्ट्रिंग दर्ज करें: bc def ghij
"घीज बीसी बीसी": 9, 13, 0.692
"घीज बीसी बीसी": 9, 13, 0.692
स्ट्रिंग दर्ज करें: अब cdefghijklmnopqrstuvw xyz
"zyxwvutsrqponmlkjihgf edc ab": 50, 50, 1.000
"zyxwvutsrqponmlkjihgf edc ab": 51, 50, 1.020
स्ट्रिंग दर्ज करें: abcdefg hijklmnopqrstuvwx
"हिज्कलमोनोपक्रस्टवुवएक्स गफ़ेडकब": 38, 31, 1.226
"हिज्कलमोनोपक्रस्टवुवएक्स गफ़ेडकब": 38, 31, 1.226
स्ट्रिंग दर्ज करें: bc de fg hi jk lm no pq rs tu vw xy zc
"zc xy vw tu rs pq no lm jk hi fg de bc de": 46, 40, 1.150
"zc xy vw tu rs pq no lm jk hi fg de bc de": 53, 40, 1.325
स्ट्रिंग दर्ज करें: aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaa dcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbd
"Dcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbd aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaa एक": 502, 402, 1.249
"Dcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbcbd aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaa एक": 502, 402, 1.249

आप देख सकते हैं कि तीसरे उदाहरण में होस्ट वर्ड-रिवर्सल एल्गोरिदम के सबसे खराब मामले को छोड़कर स्कोर लगभग समान है, जिसके लिए मेरा दृष्टिकोण 1.25 से कम का स्कोर देता है

DEBUG = False

def find_new_idx(string, pos, char, f_start, f_end, b_start, b_end, f_long):
    if DEBUG: print 'Finding new idx for s[%d] (%s)' % (pos, char)
    if f_long == 0:
        f_limit = f_end-1
        b_limit = b_start
    elif f_long == 1:
        f_limit = f_end-1
        b_limit = b_start+1
    elif f_long == -1:
        f_limit = f_end-2
        b_limit = b_start
    elif f_long == -2:
        f_limit = f_end
        b_limit = b_start

    if (f_start <= pos < f_limit or b_limit < pos < b_end) and char == ' ':
        word_start = pos
        word_end = pos+1
    else:
        if pos < f_limit+1:
            word_start = f_start
            if DEBUG: print 'Assigned word_start from f_start (%d)' % f_start
        elif pos == f_limit+1:
            word_start = f_limit+1
            if DEBUG: print 'Assigned word_start from f_limit+1 (%d)' % (f_limit+1)
        elif b_limit <= pos:
            word_start = b_limit
            if DEBUG: print 'Assigned word_start from b_limit (%d)' % b_limit
        elif b_limit-1 == pos:
            word_start = b_limit-1
            if DEBUG: print 'Assigned word_start from b_limit-1 (%d)' % (b_limit-1)
        i = pos
        while f_start <= i <= f_limit or 0 < b_limit <= i < b_end:
            if i==f_limit or i==b_limit:
                cur_char = 'a'
            elif i!=pos:
                cur_char = string[i]
            else:
                cur_char = char
            if cur_char == ' ':
                word_start = i+1
                if DEBUG: print 'Assigned word_start from loop'
                break
            i -= 1

        if b_limit <= pos:
            word_end = b_end
            if DEBUG: print 'Assigned word_end from b_end (%d)' % b_end
        elif b_limit-1 == pos:
            word_end = b_limit
            if DEBUG: print 'Assigned word_end from b_limit (%d)' % (b_limit)
        elif pos < f_limit+1:
            word_end = f_limit+1
            if DEBUG: print 'Assigned word_end from f_limit+1 (%d)' % (f_limit+1)
        elif pos == f_limit+1:
            word_end = f_limit+2
            if DEBUG: print 'Assigned word_end from f_limit+2 (%d)' % (f_limit+2)
        i = pos
        while f_start <= i <= f_limit or 0 < b_limit <= i < b_end:
            if i==f_limit or i==b_limit:
                cur_char = 'a'
            elif i!=pos:
                cur_char = string[i]
            else:
                cur_char = char
            if cur_char == ' ':
                word_end = i
                if DEBUG: print 'Assigned word_end from loop'
                break
            i += 1
    if DEBUG: print 'start, end: %d, %d' % (word_start, word_end)
    word_len = word_end - word_start
    offset = word_start-f_start
    result = (b_end-offset-(word_end-pos)) % b_end
    if string[result] == ' ' and (b_start == -1 or result not in {f_end-1, b_start}):
        return len(string)-1-result
    else:
        return result

def process_loop(string, start_idx, f_start, f_end, b_start, b_end=-1, f_long=-2, dry_run=False):
    assignments = 0
    pos = start_idx
    tmp = string[pos]
    processed_something = False
    count = 0
    while pos != start_idx or not processed_something:
        count += 1
        if DEBUG and count > 20:
            print '>>>>>Break!<<<<<'
            break
        new_pos = find_new_idx(string, pos, tmp, f_start, f_end, b_start, b_end, f_long)
        if DEBUG:
            if dry_run:
                print 'Test:',
            else:
                print '\t',
            print 'New idx for s[%d] (%s): %d (%s)' % (pos, tmp, new_pos, string[new_pos])
        if dry_run:
            tmp = string[new_pos]
            if new_pos == dry_run:
                return True
        elif pos == new_pos:
            break
        elif tmp == string[new_pos]:
            pass
        else:
            tmp, string[new_pos] = string[new_pos], tmp
            assignments += 1
        pos = new_pos
        processed_something = True
    if dry_run:
        return False
    return assignments

def reverse(string, f_start, f_end, b_start, b_end=-1, f_long=-2):
    if DEBUG: print 'reverse: %d %d %d %d %d' % (f_start, f_end, b_start, b_end, f_long)
    if DEBUG: print
    if DEBUG: print ''.join(string)
    assignments = 0
    n = len(string)
    if b_start == -1:
        for i in range(f_start, f_end):
            if string[i] == ' ':
                continue
            if DEBUG: print 'Starting from i=%d' % i
            if any(process_loop(string, j, f_start, f_end, -1, f_end, dry_run=i) for j in range(f_start, i) if string[j] != ' '):
                continue
            if DEBUG:
                print
                print 'Finished test'
            assignments += process_loop(string, i, f_start, f_end, -1, f_end)
            if DEBUG: print
            if DEBUG: print ''.join(string)
        for i in range(f_start, (f_start+f_end-1)/2):
            if (string[i] == ' ' and string[n-1-i] != ' ') or (string[i] != ' ' and string[n-1-i] == ' '):
                string[i], string[n-1-i] = string[n-1-i], string[i]
                assignments += 2
    else:
        for i in range(f_start, f_end)+range(b_start, b_end):
            if string[i] == ' ' and i not in {f_end-1, b_start}:
                continue
            if DEBUG: print 'Starting from i=%d' % i
            if any(process_loop(string, j, f_start, f_end, b_start, b_end, f_long, i) for j in range(f_start, f_end)+range(b_start, b_end) if j<i and (string[j] != ' ' or j in {f_end-1, b_start})):
                continue
            assignments += process_loop(string, i, f_start, f_end, b_start, b_end, f_long)
            if DEBUG: print
            if DEBUG: print ''.join(string)
        for i in range(f_start, f_end-1):
            if (string[i] == ' ' and string[n-1-i] != ' ') or (string[i] != ' ' and string[n-1-i] == ' '):
                string[i], string[n-1-i] = string[n-1-i], string[i]
                assignments += 2
    return assignments

class SuperList(list):
    def index(self, value, start_idx=0):
        try:
            return self[:].index(value, start_idx)
        except ValueError:
            return -1

    def rindex(self, value, end_idx=-1):
        end_idx = end_idx % (len(self)+1)
        try:
            result = end_idx - self[end_idx-1::-1].index(value) - 1
        except ValueError:
            return -1
        return result

def min_reverse(string):
    assignments = 0
    lower = 0
    upper = len(string)
    while lower < upper:
        front = string.index(' ', lower) % (upper+1)
        back = string.rindex(' ', upper)
        while abs(front-lower - (upper-1-back)) > 1 and front < back:
            if front-lower < (upper-1-back):
                front = string.index(' ', front+1) % (upper+1)
            else:
                back = string.rindex(' ', back)
            if DEBUG: print lower, front, back, upper
        if front > back:
            break
        if DEBUG: print lower, front, back, upper
        if abs(front-lower - (upper-1-back)) > 1:
            assignments += reverse(string, lower, upper, -1)
            lower = upper
        elif front-lower < (upper-1-back):
            assignments += reverse(string, lower, front+1, back+1, upper, -1)
            lower = front+1
            upper = back+1
        elif front-lower > (upper-1-back):
            assignments += reverse(string, lower, front, back, upper, 1)
            lower = front
            upper = back
        else:
            assignments += reverse(string, lower, front, back+1, upper, 0)
            lower = front+1
            upper = back
    return assignments

def minier_find_new_idx(string, pos, char):
    n = len(string)
    try:
        word_start = pos - next(i for i, char in enumerate(string[pos::-1]) if char == ' ') + 1
    except:
        word_start = 0
    try:
        word_end = pos + next(i for i, char in enumerate(string[pos:]) if char == ' ')
    except:
        word_end = n
    word_len = word_end - word_start
    offset = word_start
    result = (n-offset-(word_end-pos))%n
    if string[result] == ' ':
        return n-result-1
    else:
        return result

def minier_process_loop(string, start_idx, dry_run=False):
    assignments = 0
    pos = start_idx
    tmp = string[pos]
    processed_something = False
    while pos != start_idx or not processed_something:
        new_pos = minier_find_new_idx(string, pos, tmp)
        #print 'New idx for s[%d] (%s): %d (%s)' % (pos, tmp, new_pos, string[new_pos])
        if pos == new_pos:
            break
        elif dry_run:
            tmp = string[new_pos]
            if new_pos == dry_run:
                return True
        elif tmp == string[new_pos]:
            pass
        else:
            tmp, string[new_pos] = string[new_pos], tmp
            assignments += 1
        pos = new_pos
        processed_something = True
    if dry_run:
        return False
    return assignments

def minier_reverse(string):
    assignments = 0
    for i in range(len(string)):
        if string[i] == ' ':
            continue
        if any(minier_process_loop(string, j, dry_run=i) for j in range(i) if string[j] != ' '):
            continue
        assignments += minier_process_loop(string, i)
    n = len(string)
    for i in range(n/2):
        if string[i] == ' ' and string[n-i-1] != ' ':
            string[i], string[n-i-1] = string[n-i-1], string[i]
            assignments += 2
        elif string[n-i-1] == ' ' and string[i] != ' ':
            string[i], string[n-i-1] = string[n-i-1], string[i]
            assignments += 2
    return assignments

def main():
    while True:
        str_input = raw_input('Enter string: ')
        string = SuperList(str_input)
        result = min_reverse(string)
        n = len(string)
        print '"%s": %d, %d, %.3f' % (''.join(string), result, n, 1.0*result/n)
        string = SuperList(str_input)
        result2 = minier_reverse(string)
        print '"%s": %d, %d, %.3f' % (''.join(string), result2, n, 1.0*result2/n)

if __name__ == '__main__':
    main()

पायथन, स्कोर: 1.5

असाइनमेंट की सही संख्या सूत्र द्वारा अनुमानित की जा सकती है:

n <= 1.5 * लंबाई (स्ट्रिंग)

सबसे खराब स्थिति के साथ:

abcdefghi jklmnopqrstuvwxyzzz

37 के साथ स्ट्रिंग पर 55 असाइनमेंट के साथ।

यह विचार मेरे पिछले एक के समान है, यह सिर्फ इस संस्करण में है कि मैंने सबसे अधिक 1. लंबाई में अंतर के साथ उपसर्ग और प्रत्यय खोजने की कोशिश की। फिर मैं उस उपसर्ग और प्रत्यय पर अपने पिछले एल्गोरिथ्म को चलाता हूं (कल्पना करें कि उन्हें संक्षिप्त किया जा रहा है) । फिर असंसाधित हिस्से पर जारी रखें।

उदाहरण के लिए, पिछले सबसे खराब स्थिति के लिए:

अब | अब | सी

हम पहले "ab" और "c" (4 असाइनमेंट) पर शब्द को उलटा कर देंगे:

सी | अब | अब

हम जानते हैं कि सीमा पर यह स्थान हुआ करता था (कई मामलों को संभालने के लिए है, लेकिन आप ऐसा कर सकते हैं), इसलिए हमें सीमा पर अंतरिक्ष को घेरने की आवश्यकता नहीं है, यह पिछले एल्गोरिथ्म से मुख्य सुधार है। ।

फिर अंत में हम पाने के लिए मध्य चार वर्णों पर चलते हैं:

cba ab

कुल 8 असाइनमेंट में, इस मामले के लिए इष्टतम, क्योंकि सभी 8 अक्षर बदल गए।

यह पिछले एल्गोरिथम में सबसे खराब स्थिति को समाप्त करता है क्योंकि पिछले एल्गोरिथ्म में सबसे खराब मामला समाप्त हो गया है।

कुछ नमूना रन देखें (और @ प्राइमो के जवाब के साथ तुलना करें - वह दूसरी पंक्ति है):

स्ट्रिंग दर्ज करें: मैं कुछ भी कर सकता हूं
"कुछ भी मैं कर सकता हूँ": 20, 17
"कुछ भी मैं कर सकता हूं": 17, 17
स्ट्रिंग दर्ज करें: abcdef ghijklmnopqrs
"ग़ज़लक्म्नोपकार्स फेडकब": ३m, २५
"ग़ज़लक्म्नोपकार्स फेडकब": ३१, २५
स्ट्रिंग दर्ज करें: abcdef ghijklmnopqrst
"ग़ज़लक्म्नोपक्रस्ट फेडकब": 38, 26
"ग़ज़लक्म्नोपक्रस्ट फेडकब": 32, 26
स्ट्रिंग दर्ज करें: abcdefghi jklmnozzzzzzzzzzzzzzzzzzz
"jklmnozzzzzzzzzzzzzzzzzzzzz ihgfedcb a": 59, 41
"jklmnozzzzzzzzzzzzzzzzzzzzz ihgfedcb a": 45, 41
स्ट्रिंग दर्ज करें: abcdefghi jklmnopqrstuvwxyzzz
"jklmnopqrstuvwxyzzz ihgfedcb a": 55, 37
"jklmnopqrstuvwxyzzz ihgfedcb a": 45, 37
स्ट्रिंग दर्ज करें: ab ababababababac
"काबाबाबाबाबा अब्बू": 30, 30
"काबाबाज़ाबाबा अब": 31, 30
स्ट्रिंग दर्ज करें: ab abababababababc
"cbababababababa ab": 32, 32
"cbababababababa ab": 33, 32
स्ट्रिंग दर्ज करें: एबीसी डी एबीसी
"एबीसी डी एबीसी": 0, 9
"एबीसी डी एबीसी": 0, 9
स्ट्रिंग दर्ज करें: एबीसी dca
"एसीडी एबीसी": 6, 9
"एसीडी एबीसी": 4, 9
स्ट्रिंग दर्ज करें: abc ababababababc
"cbabababababa abc": 7, 29
"cbabababababa abc": 5, 29

प्राइमो का जवाब आम तौर पर बेहतर होता है, हालांकि कुछ मामलों में मुझे 1 अंक का फायदा हो सकता है =)

इसके अलावा उसका कोड मेरा, हाहा से बहुत छोटा है।

DEBUG = False

def find_new_idx(string, pos, char, f_start, f_end, b_start, b_end, f_long):
    if DEBUG: print 'Finding new idx for s[%d] (%s)' % (pos, char)
    if f_long == 0:
        f_limit = f_end-1
        b_limit = b_start
    elif f_long == 1:
        f_limit = f_end-1
        b_limit = b_start+1
    elif f_long == -1:
        f_limit = f_end-2
        b_limit = b_start
    elif f_long == -2:
        f_limit = f_end
        b_limit = b_start

    if (f_start <= pos < f_limit or b_limit < pos < b_end) and (char == ' ' or char.isupper()):
        word_start = pos
        word_end = pos+1
    else:
        if pos < f_limit+1:
            word_start = f_start
            if DEBUG: print 'Assigned word_start from f_start (%d)' % f_start
        elif pos == f_limit+1:
            word_start = f_limit+1
            if DEBUG: print 'Assigned word_start from f_limit+1 (%d)' % (f_limit+1)
        elif b_limit <= pos:
            word_start = b_limit
            if DEBUG: print 'Assigned word_start from b_limit (%d)' % b_limit
        elif b_limit-1 == pos:
            word_start = b_limit-1
            if DEBUG: print 'Assigned word_start from b_limit-1 (%d)' % (b_limit-1)
        i = pos
        if not (i < f_limit and b_limit < i):
            i -= 1
        while f_start <= i < f_limit or 0 < b_limit < i < b_end:
            if i!=pos:
                cur_char = string[i]
            else:
                cur_char = char
            if cur_char == ' ' or cur_char.isupper():
                word_start = i+1
                if DEBUG: print 'Assigned word_start from loop'
                break
            i -= 1

        if b_limit <= pos:
            word_end = b_end
            if DEBUG: print 'Assigned word_end from b_end (%d)' % b_end
        elif b_limit-1 == pos:
            word_end = b_limit
            if DEBUG: print 'Assigned word_end from b_limit (%d)' % (b_limit)
        elif pos < f_limit+1:
            word_end = f_limit+1
            if DEBUG: print 'Assigned word_end from f_limit+1 (%d)' % (f_limit+1)
        elif pos == f_limit+1:
            word_end = f_limit+2
            if DEBUG: print 'Assigned word_end from f_limit+2 (%d)' % (f_limit+2)
        i = pos
        if not (i < f_limit and b_limit < i):
            i += 1
        while f_start <= i < f_limit or 0 < b_limit < i < b_end:
            if i!=pos:
                cur_char = string[i]
            else:
                cur_char = char
            if cur_char == ' ' or cur_char.isupper():
                word_end = i
                if DEBUG: print 'Assigned word_end from loop'
                break
            i += 1
    if DEBUG: print 'start, end: %d, %d' % (word_start, word_end)
    word_len = word_end - word_start
    offset = word_start-f_start
    return (b_end-offset-(word_end-pos)) % b_end

def process_loop(string, start_idx, f_start, f_end, b_start, b_end=-1, f_long=-2, dry_run=False):
    assignments = 0
    pos = start_idx
    tmp = string[pos]
    processed_something = False
    count = 0
    while pos != start_idx or not processed_something:
        count += 1
        if count > 20:
            if DEBUG: print 'Break!'
            break
        new_pos = find_new_idx(string, pos, tmp, f_start, f_end, b_start, b_end, f_long)
        #if dry_run:
        #    if DEBUG: print 'Test:',
        if DEBUG: print 'New idx for s[%d] (%s): %d (%s)' % (pos, tmp, new_pos, string[new_pos])
        if pos == new_pos:
            break
        elif dry_run:
            tmp = string[new_pos]
            if new_pos == dry_run:
                return True
        elif tmp == string[new_pos]:
            pass
        elif tmp == ' ':
            if b_start!=-1 and new_pos in {f_end-1, b_start}:
                tmp, string[new_pos] = string[new_pos], tmp
            else:
                tmp, string[new_pos] = string[new_pos], '@'
            assignments += 1
        elif string[new_pos] == ' ':
            if b_start!=-1 and new_pos in {f_end-1, b_start}:
                tmp, string[new_pos] = string[new_pos], tmp
            else:
                tmp, string[new_pos] = string[new_pos], tmp.upper()
            assignments += 1
        else:
            tmp, string[new_pos] = string[new_pos], tmp
            assignments += 1
        pos = new_pos
        processed_something = True
    if dry_run:
        return False
    return assignments

def reverse(string, f_start, f_end, b_start, b_end=-1, f_long=-2):
    if DEBUG: print 'reverse: %d %d %d %d %d' % (f_start, f_end, b_start, b_end, f_long)
    if DEBUG: print
    if DEBUG: print ''.join(string)
    assignments = 0
    if b_start == -1:
        for i in range(f_start, (f_start+f_end)/2):
            if DEBUG: print 'Starting from i=%d' % i
            if any(process_loop(string, j, f_start, f_end, -1, f_end, dry_run=i) for j in range(f_start, i)):
                continue
            assignments += process_loop(string, i, f_start, f_end, -1, f_end)
            if DEBUG: print
            if DEBUG: print ''.join(string)
    else:
        for i in range(f_start, f_end):
            if DEBUG: print 'Starting from i=%d' % i
            if any(process_loop(string, j, f_start, f_end, b_start, b_end, f_long, i) for j in range(f_start, i)):
                continue
            assignments += process_loop(string, i, f_start, f_end, b_start, b_end, f_long)
            if DEBUG: print
            if DEBUG: print ''.join(string)
    for i in range(len(string)):
        if string[i] == '@':
            string[i] = ' '
            assignments += 1
        if string[i].isupper():
            string[i] = string[i].lower()
            assignments += 1
    return assignments

class SuperList(list):
    def index(self, value, start_idx=0):
        try:
            return self[:].index(value, start_idx)
        except ValueError:
            return -1

    def rindex(self, value, end_idx=-1):
        end_idx = end_idx % (len(self)+1)
        try:
            result = end_idx - self[end_idx-1::-1].index(value) - 1
        except ValueError:
            return -1
        return result

def min_reverse(string):
    # My algorithm
    assignments = 0
    lower = 0
    upper = len(string)
    while lower < upper:
        front = string.index(' ', lower) % (upper+1)
        back = string.rindex(' ', upper)
        while abs(front-lower - (upper-1-back)) > 1 and front < back:
            if front-lower < (upper-1-back):
                front = string.index(' ', front+1) % (upper+1)
            else:
                back = string.rindex(' ', back)
            if DEBUG: print lower, front, back, upper
        if front > back:
            break
        if DEBUG: print lower, front, back, upper
        if abs(front-lower - (upper-1-back)) > 1:
            assignments += reverse(string, lower, upper, -1)
            lower = upper
        elif front-lower < (upper-1-back):
            assignments += reverse(string, lower, front+1, back+1, upper, -1)
            lower = front+1
            upper = back+1
        elif front-lower > (upper-1-back):
            assignments += reverse(string, lower, front, back, upper, 1)
            lower = front
            upper = back
        else:
            assignments += reverse(string, lower, front, back+1, upper, 0)
            lower = front+1
            upper = back
    return assignments

def minier_find_new_idx(string, pos, char):
    n = len(string)
    try:
        word_start = pos - next(i for i, char in enumerate(string[pos::-1]) if char == ' ') + 1
    except:
        word_start = 0
    try:
        word_end = pos + next(i for i, char in enumerate(string[pos:]) if char == ' ')
    except:
        word_end = n
    word_len = word_end - word_start
    offset = word_start
    result = (n-offset-(word_end-pos))%n
    if string[result] == ' ':
        return n-result-1
    else:
        return result

def minier_process_loop(string, start_idx, dry_run=False):
    assignments = 0
    pos = start_idx
    tmp = string[pos]
    processed_something = False
    while pos != start_idx or not processed_something:
        new_pos = minier_find_new_idx(string, pos, tmp)
        #print 'New idx for s[%d] (%s): %d (%s)' % (pos, tmp, new_pos, string[new_pos])
        if pos == new_pos:
            break
        elif dry_run:
            tmp = string[new_pos]
            if new_pos == dry_run:
                return True
        elif tmp == string[new_pos]:
            pass
        else:
            tmp, string[new_pos] = string[new_pos], tmp
            assignments += 1
        pos = new_pos
        processed_something = True
    if dry_run:
        return False
    return assignments

def minier_reverse(string):
    # primo's answer for comparison
    assignments = 0
    for i in range(len(string)):
        if string[i] == ' ':
            continue
        if any(minier_process_loop(string, j, dry_run=i) for j in range(i) if string[j] != ' '):
            continue
        assignments += minier_process_loop(string, i)
    n = len(string)
    for i in range(n/2):
        if string[i] == ' ' and string[n-i-1] != ' ':
            string[i], string[n-i-1] = string[n-i-1], string[i]
            assignments += 2
        elif string[n-i-1] == ' ' and string[i] != ' ':
            string[i], string[n-i-1] = string[n-i-1], string[i]
            assignments += 2
    return assignments

def main():
    while True:
        str_input = raw_input('Enter string: ')
        string = SuperList(str_input)
        result = min_reverse(string)
        print '"%s": %d, %d' % (''.join(string), result, len(string))
        string = SuperList(str_input)
        result2 = minier_reverse(string)
        print '"%s": %d, %d' % (''.join(string), result2, len(string))

if __name__ == '__main__':
    main()

अजगर, स्कोर: सामान्य रूप से बहुत कम, विषम 2,

अंतरिक्ष अवरोध के कारण हटा दिया गया पुराना कोड

विचार प्रत्येक सूचकांक के माध्यम से पुनरावृति है, और प्रत्येक सूचकांक के लिए i, हम चरित्र ले, नई स्थिति की गणना j, के स्थान पर चरित्र को याद j, पर चरित्र आवंटित iकरने के लिए jसूचकांक में चरित्र के साथ, और बार-बार j। चूंकि हमें नई स्थिति की गणना करने के लिए अंतरिक्ष जानकारी की आवश्यकता है, इसलिए मैं पुराने स्थान को नए अक्षर के अपरकेस संस्करण के रूप में और नए स्थान को '@' के रूप में एन्कोड करता हूं।


यदि आप स्ट्रिंग की लंबाई के मामले में बदतर स्थिति में शब्दों की संख्या को कम कर सकते हैं (जैसे, length(string)/3प्रत्येक शब्द को सबसे खराब स्थिति में किसी भी तरह से कम से कम 2 की लंबाई के लिए मजबूर करना), तो स्कोर से कम होगा 2 (यह ऊपर के उदाहरण में हो जाएगा 1.67)
justhalf

1
मैंने अपने लिए एक स्वैप काउंटर जोड़ा; तुम्हारा वास्तव में सबसे बुरे मामले (लेकिन सामान्य मामला नहीं) के लिए मुझे हरा देता है। इसे ठीक करने का एक तरीका खोजने की आवश्यकता है;)
प्राइमो

पंक्ति १२ if any(process_loop(...) for j in range(...))process: इन प्रक्रियाओं से काम नहीं करना चाहिए छोरों की गणना करने की आवश्यकता है?
प्रिमो

यह कोई काम नहीं करता है। यदि आप देखते हैं, तो dry_runपैरामीटर गैर-शून्य (मान i) पर सेट है। process_loopयदि dry_runगैर-शून्य है , तो अंदर , यह कोई असाइनमेंट नहीं करेगा।
प्रातः

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

14

पर्ल, स्कोर 1.3l

प्रत्येक गैर-स्थान वर्ण के लिए एक असाइनमेंट किया जाता है, और प्रत्येक स्थान वर्ण के लिए दो असाइनमेंट होते हैं। क्योंकि अंतरिक्ष वर्ण कुल वर्णों की संख्या से आधे से अधिक नहीं हो सकते, इसलिए सबसे खराब स्थिति स्कोर है 1.5 है

एल्गोरिथ्म नहीं बदला है, लेकिन मैं एक ऊपरी ऊपरी सीमा को साबित कर सकता हूं। आइए हम दो अवलोकन करें:

  1. रिक्त स्थान से सीधे रिक्त स्थान को स्वैप करने की आवश्यकता नहीं है।
  2. रिक्त स्थान से सीधे एकल वर्ण शब्द मुख्य चरण के दौरान स्वैप नहीं किए जाते हैं, लेकिन केवल एक बार अंत में।

फिर यह देखा जा सकता है कि asymptotically 1/2 रिक्त स्थान के साथ सैद्धांतिक 'सबसे खराब मामला' सबसे खराब स्थिति नहीं है: ab c d e f g h i ...

$ echo ab c d e f g h i j k l m n o p q r s t u v w x y z|perl reverse-inplace.pl
z y x w v u t s r q p o n m l k j i h g f e d c ab
swaps: 51; len: 50
ratio: 1.02

वास्तव में, यह काफी अच्छा मामला है।

उपरोक्त एक और दो के अवलोकन को रोकने के लिए, प्रत्येक एक-वर्ण शब्द को तीन या तीन से अधिक वर्णों के बीच में स्थान देना होगा। यह सुझाव देगा कि सबसे खराब स्थिति में 1/3 स्थान हों:a bcd a bcd a ... bc

$ echo a bcd a bcd a bcd a bcd a bcd a bc|perl reverse-inplace.pl
bc a bcd a bcd a bcd a bcd a bcd a
swaps: 45; len: 34
ratio: 1.32352941176471

या समकक्ष, केवल दो-वर्ण शब्द: a bc de fg hi jk ...

$ echo a bc de fg hi jk lm no pq rs tu vx xy|perl reverse-inplace.pl
xy vx tu rs pq no lm jk hi fg de bc a
swaps: 49; len: 37
ratio: 1.32432432432432

क्योंकि सबसे खराब स्थिति में asymptotically 1/3 स्थान होते हैं, इसलिए सबसे खराब स्थिति स्कोर 1.3 as हो जाता है

#!perl -l
use warnings;

$words = <>;
chomp($words);
$len = length($words);
$words .= ' ';
$spaces = 0;
# iterate over the string, count the spaces
$spaces++ while $words =~ m/ /g;

$origin = 0;
$o = vec($words, $origin, 8);
$cycle_begin = $origin;
$swaps = 0;

# this possibly terinates one iteration early,
# if the last char is a one-cycle (i.e. moves to its current location)
# one-cycles previous to the last are iterated, but not swapped.
while ($i++ < $len - $spaces || !$was_cycle) {
  $w_start = rindex($words, ' ', $origin);
  $w_end = index($words, ' ', $origin);
  $pos = ($origin - $w_start) - 1;
  $target = $len - ($w_end - $pos);
  $t = vec($words, $target, 8);

  if ($t == 32) {
    $target = $len - $target - 1;
    $t = vec($words, $target, 8);
  }

  # char is already correct, possibly a one-cycle
  if ($t != $o) {
    $swaps += 1;
    vec($words, $target, 8) = $o;
  }

  $origin = $target;
  $o = $t;
  if ($origin == $cycle_begin) {
    if ($i < $len - $spaces) {
      # backtrack through everything we've done up to this point
      # to find the next unswapped char ...seriously.
      $origin += 1;
      if (vec($words, $origin, 8) == 32) {
        $origin += 1;
      }
      $bt_origin = 0;
      $bt_cycle_begin = 0;
      while ($bt_cycle_begin < $origin) {
        $w_start = rindex($words, ' ', $bt_origin);
        $w_end = index($words, ' ', $bt_origin);
        $pos = ($bt_origin - $w_start) - 1;
        $target = $len - ($w_end - $pos);
        $t = vec($words, $target, 8);

        if ($t == 32) {
          $target = $len - $target - 1;
          $t = vec($words, $target, 8);
        }

        if ($target == $bt_cycle_begin) {
          $bt_origin = ++$bt_cycle_begin;
          if (vec($words, $bt_origin, 8) == 32) {
            $bt_origin = ++$bt_cycle_begin;
          }
        } else {
          $bt_origin = $target;
        }

        if ($target == $origin) {
          $origin += 1;
          if (vec($words, $origin, 8) == 32) {
            $origin += 1;
          }
          $bt_origin = $bt_cycle_begin = 0;
        }
      }
    }

    $cycle_begin = $origin;
    $o = vec($words, $origin, 8);
    $was_cycle = 1;
  } else {
    $was_cycle = 0;
  }
}

for $i (0..$len/2-1) {
  $mirror = $len - $i - 1;
  $o = vec($words, $i, 8);
  $m = vec($words, $mirror, 8);
  # if exactly one is a space...
  if (($o == 32) ^ ($m == 32)) {
    $swaps += 2;
    vec($words, $mirror, 8) = $o;
    vec($words, $i, 8) = $m;
  }
}

chop($words);
print $words;
print "swaps: $swaps; len: $len";
print 'ratio: ', $swaps/$len;

संपादित करें: एक स्वैप काउंटर और अनुपात जोड़ा गया।

इनपुट स्टड से लिया गया है। नमूना उपयोग:

$ echo where in the world is carmen sandiego|perl reverse-inplace.pl
sandiego carmen is world the in where
swaps: 35; len: 37
ratio: 0.945945945945946

तरीका

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

  1. चरित्र को एक स्थान के साथ स्वैप किया जाना चाहिए।
    जब ऐसा होता है, तो चरित्र है अंतरिक्ष के साथ स्वैप नहीं किया जाता है, बल्कि अंतरिक्ष की दर्पण स्थिति में। एल्गोरिथ्म उस स्थिति से जारी है।
  2. एक चक्र तक पहुँच गया है।
    जब लक्ष्य वर्तमान चक्र की प्रारंभिक प्रारंभिक स्थिति में वापस आ जाता है, तो अगला अज्ञात चरित्र (या यों कहें, कोई भी अज्ञात चरित्र क्या करेगा) ढूंढने की आवश्यकता है। लगातार मेमोरी की कमी के तहत ऐसा करने के लिए, इस बिंदु पर किए गए सभी स्वैप बैक-ट्रैक किए जाते हैं।

इस चरण के बाद, प्रत्येक गैर-स्थान चरित्र को एक बार में स्थानांतरित कर दिया गया है। खत्म करने के लिए, सभी अंतरिक्ष पात्रों को उनके दर्पण पदों पर पात्रों के साथ स्वैप किया जाता है, जिन्हें प्रति स्थान दो असाइनमेंट संचालन की आवश्यकता होती है।


वाह ये अच्छा है। क्या आप बता सकते हैं कि चरित्र को अंतरिक्ष की मिरर पोजीशन में रखना सही उत्तर क्यों देता है?
justhalf

1
@ निक्लास, मुझे नहीं लगता कि यह संभव है। क्योंकि बैकट्रैकिंग करने के लिए आपको स्पेस पोजीशन की जानकारी चाहिए। यदि आप उस जानकारी को ओवरराइड करते हैं, तो आप बैकट्रैकिंग नहीं कर सकते।
justhalf

1
मैं अपने उत्तर में अपने एल्गोरिथ्म के खिलाफ एक तुलना कर रहा हूँ: codegolf.stackexchange.com/a/26952/16337
अभी

1
@ अन्याय को अंतिम स्ट्रिंग में, सभी रिक्त स्थान उनके प्रतिबिंबित स्थिति में होंगे। इसलिए, हम इस स्थिति का उपयोग अंतरिक्ष को बदलने वाले चरित्र को संग्रहीत करने के लिए सुरक्षित रूप से कर सकते हैं, और अंत में उन्हें स्विच कर सकते हैं।
प्रिमो

1
बहुत बढ़िया। मेरे पास एक समान विचार था, लेकिन केवल रिक्त स्थान छोड़ने और फिर उन्हें प्रतिबिंबित करने के बारे में नहीं सोचा था।
IchBinKeinBaum

7

रूबी, स्कोर २

स्टार्टर के रूप में एक बहुत ही बुनियादी एल्गोरिथ्म। यह पहले पूरे स्ट्रिंग को उलट देता है और फिर प्रत्येक शब्द को फिर से स्ट्रिंग में उलट देता है। सबसे खराब स्थिति में (एक शब्द, यहां तक ​​कि वर्णों की संख्या) स्कोर 2 हो जाता है।

def revstring(s, a, b)
  while a<b
    h = s[a]
    s[a] = s[b]
    s[b] = h
    a += 1
    b -= 1
  end
  s
end

def revwords(s)
  revstring(s, 0, s.length-1)
  a = 0
  while a<s.length
    b = a+1
    b += 1 while b<s.length and s[b]!=" "
    revstring(s, a, b-1)
    a = b+1
  end
  s
end

उपयोग:

> revwords("hello there everyone")
"everyone there hello"

एक स्ट्रिंग को उलटने के लिए आपने रूबी बिल्ट-इन फ़ंक्शन का उपयोग क्यों नहीं किया? क्या यह स्कोर को बदल देगा?
एएल

उपयोग करें, s [a], s [b] = s [b], s [a]
थापा kp

5

C ++: स्कोर 2

#include<iostream>
#include<algorithm>

void rev(std::string& s)
{
    std::reverse(s.begin(),s.end());
    std::string::iterator i=s.begin(),j=s.begin();
    while(i!=s.end())
    {
        while(i!=s.end()&&(*i)==' ')
            i++;
        j=i;
        while(i!=s.end()&&(*i)!=' ')
            i++;
        std::reverse(j,i);
    }
}

int main()
{
    std::string s;
    getline(std::cin,s);
    rev(s);
    std::cout<<s;
}

2
मैंने इसका परीक्षण किया। अच्छा काम करता है!
बेचेसबेल

2

REBOL

reverse-words: function [
    "Reverse the order of words. Modifies and returns string (series)"
    series [string!] "At position (modified)"
  ][
    first-time: on
    until [
        reverse/part series f: any [
            if first-time [tail series]
            find series space
            tail series
        ]
        unless first-time [series: next f]
        first-time: off
        tail? series
    ]

    series: head series
]

मैं इसके लिए स्कोरिंग पर अस्पष्ट हूं। इस कोड में कोई सीधा स्ट्रिंग असाइनमेंट नहीं है। सब कुछ एक के द्वारा नियंत्रित किया जाता हैreverse/part जो भीतर-भीतर उलट-पुलट करता है और शुरू में पूरे तार पर।

कोड पर कुछ विवरण:

  • स्ट्रिंग के माध्यम से लूप (series ) जब तक यह नहीं पहुंचताtail?

  • लूप में पहली बार स्ट्रिंग का पूरा उल्टा करें - reverse/part series tail series (जो कि जैसा है reverse series)

  • फिर आगे के पुनरावृत्तियों पर पाए जाने वाले प्रत्येक शब्द को उल्टा करें - reverse/part series find series space

  • एक बार थका हुआ शब्द मिल जाए तो वापस लौट जाएं tail series ताकि यह स्ट्रिंग में अंतिम शब्द को उलट देगा -reverse/part series tail series

Rebol आंतरिक सूचक के माध्यम से एक स्ट्रिंग का पता लगाने की अनुमति देता है । आप इसे देख सकते हैं series: next f(अगले शब्द की शुरुआत के बाद स्थान के लिए संकेतक ले जाएँ) औरseries: head series (रीसेट सूचक वापस सिर पर)।

देख श्रृंखलाअधिक जानकारी के लिए ।

Rebol कंसोल में उपयोग उदाहरण:

>> reverse-words "everyone there hello"
== "hello there everyone"

>> x: "world hello"
== "world hello"

>> reverse-words x
== "hello world"

>> x
== "hello world"

>> reverse-words "hello"
== "hello"

पहले पास पर प्रत्येक वर्ण को एक बार रिपॉजिट किया जाता है, और दूसरे पास पर प्रत्येक गैर-स्पेस चरित्र को फिर से रिपोज किया जाता है। अपेक्षाकृत कुछ स्थानों के साथ एक बड़े पैमाने पर इनपुट के लिए, स्कोर 2. पर पहुंच जाता है
प्राइमो

2

C: स्कोर 2

यह बस एक बार फिर प्रत्येक शब्द को उलटता है, पूरे स्ट्रिंग को फ़्लिप करता है।

#include <stdio.h>
#include <string.h>

void reverse(char *s,unsigned n){
    char c;
    unsigned i=0,r=1;
    while(i < n){ //no swap function in C 
        c=s[i];
        s[i++]=s[n];
        s[n--]=c;
    }
}

unsigned wordlen(char *s){
    unsigned i=0;
    while (s[i] != ' ' && s[i]) ++i;
    return i;
}

int main(int argc, char **argv) {
    char buf[]="reverse this also";
    char *s=buf;
    unsigned wlen=0,len=strlen(s)-1;
    reverse(s,len);  //reverse entire string
    while(wlen<len){  // iterate over each word till end of string
      wlen=wordlen(s);
      reverse(s,wlen-1);
      s+=wlen+1;
      len-=wlen;
    }
    printf("%s\n",buf);
    return 0;
}

3
यह एक कोड-ओनली उत्तर है। अपने कोड में क्या चल रहा है, इसका स्पष्टीकरण जोड़ने पर विचार करें।
जस्टिन

1

अजगर: स्कोर 2

लगभग हावर्ड के एल्गोरिथ्म के समान है, लेकिन क्या उलटा कदम रिवर्स में होता है (पहले शब्द फ़्लिप करता है फिर पूरे स्ट्रिंग को फ़्लिप करता है)। अतिरिक्त स्मृति प्रयुक्त 3 बाइट आकार चर है: i, j, और t। तकनीकी रूप से, findऔर lenकुछ आंतरिक चर का उपयोग कर रहे हैं, लेकिन वे आसानी से पुन: उपयोग iया कर सकते हैंj सकते बिना किसी नुकसान के कार्य कर सकते हैं।

त्वरित संपादन: केवल वर्णों के अलग-अलग होने पर स्ट्रिंग असाइनमेंट पर बचत होती है, इसलिए मैं नोट # 2 से कुछ अतिरिक्त अंक ले सकता हूं।

from sys import stdin

def word_reverse(string):
    # reverse each word
    i=0
    j=string.find(' ')-1
    if j == -2: j=len(string)-1
    while True:
        while i<j:
            if string[i] != string[j]:
                t = string[i]
                string[i] = string[j]
                string[j] = t
            i,j = i+1,j-1
        i=string.find(' ', i)+1
        if i==0: break
        j=string.find(' ', i)-1
        if j == -2: j=len(string)-1
    # reverse the entire string
    i=0
    j=len(string)-1
    while i<j:
        if string[i] != string[j]:
            t = string[i]
            string[i] = string[j]
            string[j] = t
        i,j = i+1,j-1
    return string

for line in stdin.readlines():
    # http://stackoverflow.com/a/3463789/1935085
    line = line.strip() # no trailing newlines ore spaces to ensure it conforms to '[a-z]+( [a-z]+)*'
    print word_reverse(bytearray(line))

1

जत्था

मैं स्कोरिंग को पूरी तरह से नहीं समझने के लिए मानता हूं (मुझे लगता है कि यह दो है) .. लेकिन मैं कहूंगा - यह बात करता है

@echo off

setLocal enableDelayedExpansion
set c=
set s=

for %%a in (%~1) do set /a c+=1 & echo %%a >> f!c!

for /L %%a in (!c!, -1, 1) do (
    set /p t=<f%%a
    set s=!s!!t!
    del f%%a
)

echo !s!

इनपुट को पहले मानक इनपुट मान के रूप में लिया जाता है, और इसलिए उद्धरण चिह्नों से घिरा होना चाहिए -
कॉल:script.bat "hello there everyone"
आउट everyone there hello:।

हो सकता है कि कोई और मुझे स्कोर कर सकता है (यह मानते हुए कि मैंने किसी और तरह से खुद को अयोग्य घोषित नहीं किया है)।


-2

जावास्क्रिप्ट

function reverseWords(input) {
    if (input.match(/^[a-z]+( [a-z]+)*$/g)) {
        return input.split(' ').reverse().join(' ');
    }
}

उपयोग:

> reverseWords('hello there everyone');
'everyone there hello'

मुझे अजीब सा एहसास हो रहा है कि मुझे कुछ याद आया ...


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

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