सबसे छोटा सबसे लंबा सामान्य परिणाम कोड


11

SLCSC समस्या को हल करने के लिए आपका कार्य, जिसमें सबसे लंबे समय तक सामान्य प्रक्रिया को हल करने के लिए सबसे कम संभव कोड ढूंढना शामिल है

के लिए दो या अधिक तार LCS समस्या का एक मान्य समाधान एस 1 , एस ... n कोई भी स्ट्रिंग है टी अधिक से अधिक लंबाई की ऐसी है कि के पात्रों टी सभी समाचारों में दिखाई एस मैं के रूप में, एक ही क्रम में टी

ध्यान दें कि T को S i का उप स्ट्रिंग होना आवश्यक नहीं है ।

उदाहरण

स्ट्रिंग्स axbyczऔर xaybzcलंबाई 3 के 8 सामान्य क्रम हैं:

abc abz ayc ayz xbc xbz xyc xyz

इनमें से कोई भी एलसीएस समस्या के लिए एक वैध समाधान होगा।

विवरण

एक कार्यक्रम या एक फ़ंक्शन लिखें जो एलसीएस समस्या को हल करता है, जैसा कि ऊपर बताया गया है, निम्नलिखित नियमों का पालन करना:

  • इनपुट में दो या अधिक स्ट्रिंग्स होंगे जिसमें केवल लोअरकेस अक्षर होंगे।

    आप उन स्ट्रिंग्स को स्ट्रिंग्स की एक सरणी के रूप में या अपनी पसंद के सीमांकक के साथ एक स्ट्रिंग के रूप में पढ़ सकते हैं।

  • आपके कोड को समस्या के संभावित समाधानों में से किसी एक को आउटपुट करना होगा, वैकल्पिक रूप से एक लाइनफीड द्वारा या उद्धरणों से घिरा होना चाहिए।

  • आप मान सकते हैं कि तार 1000 वर्णों से छोटे हैं और अधिकांश 20 तार हैं।

    इन सीमाओं के भीतर, आपके कोड को सिद्धांत रूप में अपेक्षित (असीमित समय और स्मृति को देखते हुए) काम करना चाहिए ।

  • आपके कोड को मेरी मशीन (इंटेल कोर i7-3770, 16 गीगा रैम) पर एक घंटे के भीतर अगले भाग के संयुक्त परीक्षण के मामलों को पूरा करना होगा।

    वे दृष्टिकोण जो केवल सभी संभावित बाद में पुनरावृति करते हैं, समय सीमा का अनुपालन नहीं करेंगे।

  • बिल्ट-इन का उपयोग करना जो इस कार्य को तुच्छ बनाते हैं, जैसे कि LongestCommonSequence, अनुमति नहीं है।

मानक नियम लागू होते हैं।

परीक्षण के मामलों

a
ab

आउटपुट: a


aaaaxbbbb
bbbbxcccc
ccccxaaaa

आउटपुट: x


hxbecqibzpyqhosszypghkdddykjfjcajnwfmtfhqcpavqrtoipocijrmqpgzoufkjkyurczxuhkcpehbhpsuieqgjcepuhbpronmlrcgvipvibhuyqndbjbrrzpqbdegmqgjliclcgahxoouqxqpujsyfwbdthteidvigudsuoznykkzskspjufgkhaxorbrdvgodlb
qnnprxqpnafnhekcxljyysobbpyhynvolgtrntqtjpxpchqwgtkpxxvmwwcohxplsailheuzhkbtayvmxnttycdkbdvryjkfhshulptkuarqwuidrnjsydftsyhuueebnrjvkfvhqmyrclehcwethsqzcyfvyohzskvgttggndmdvdgollryqoswviqurrqhiqrqtyrl

आउटपुट: hxbbpyhogntqppcqgkxchpsieuhbncvpuqndbjqmclchqyfttdvgoysuhrrlया समान लंबाई का कोई अन्य सामान्य परिणाम


riikscwpvsbxrvkpymvbbpmwclizxlhihiubycxmxwviuajdzoonjpkgiuiulbjdpkztsqznhbjhymwzkutmkkkhirryabricvhb
jnrzutfnbqhbaueicsvltalvqoorafnadevojjcsnlftoskhntashydksoheydbeuwlswdzivxnvcrxbgxmquvdnfairsppodznm
kzimnldhqklxyezcuyjaiasaeslicegmnwfavllanoolkhvqkjdvxrsjapqqwnrplcwqginwinktxnkfcuuvoyntrqwwucarfvjg

आउटपुट: icsvllvjnlktywuarया समान लंबाई का कोई अन्य सामान्य परिणाम


rblartqkfggrjpiipuzzypkycnyckkcqceeujiyy
yfpnedyjtiwrhyuktripdwyvgkblzodeufkelhub
ywcyboxwqkibwvredkrbdsyudkulpvmhixeqxynh
bnxwahbzhwjxkotnvbxrojkkldtsodtjmvdrmbgr

आउटपुट: krkkया समान लंबाई का कोई अन्य सामान्य परिणाम


bwfscmotshoczmduwaev
coywaaizdaxjovipsmeh
dobzcpoiedenzlfdjpiu
bbhfeqscvvbwkuoxdoge
drqrzwbcpcsvneodelja

आउटपुट: codeया समान लंबाई का कोई अन्य सामान्य परिणाम


nqrualgoedlf
jgqorzglfnpa
fgttvnogldfx
pgostsulyfug
sgnhoyjlnfvr
wdttgkolfkbt

आउटपुट: golfया समान लंबाई का कोई अन्य सामान्य परिणाम


epopyfuhgowedpiqpgfj
ddxyestqynpwmytxhozm
ptubgzyqqksieoovuezv
tovotqmnhgzttfpywjgr
aomvytkgaijlgqzkljls
vzvxpaixrnprxvenbbuo
syfuwxlpcyontqlmfvib
arxleuomstkjegpduwcx
xgqrxaopouvkvwgbzewn
yggunddigctgpnuztzai
izroomywwztdymqszsuo
kiawjnxjncdtufhkrjsp

आउटपुट: खाली स्ट्रिंग



@NotthatCharles बिल्कुल नहीं। यह प्रश्न इनपुट के रूप में केवल दो तार देता है और इसकी कोई समय सीमा नहीं है। सभी मौजूदा उत्तर भोले दृष्टिकोण का उपयोग करते हैं जो इस प्रश्न के नियमों का पालन करने के लिए परिमाण बहुत धीमा है।
डेनिस

अंतिम उदाहरण शायद गणना करने के लिए सबसे लंबा समय लेता है, हालांकि पहले हर वर्ण को हटाकर जो प्रत्येक स्ट्रिंग में प्रकट नहीं होता है यह खाली स्ट्रिंग को आउटपुट करने के लिए तुच्छ है। क्या आप एक और उदाहरण जोड़ सकते हैं तार और लंबाई की एक ही संख्या के साथ, जहां उपयोग किया जाने वाला प्रत्येक वर्ण हर स्ट्रिंग में दिखाई देता है और जहां LCS कम से कम 5 वर्ण या ऐसा है? कुछ इस तरह से: ghostbin.com/paste/x9caq
Tyilo

@Tylio कुछ तर्क को समाहित करता है जो पुनरावृत्ति को जल्द समाप्त करता है यदि स्ट्रिंग्स में कोई और अधिक सामान्य वर्ण नहीं है तो अंतिम टेस्ट केस के बारे में बहुत अधिक है।
डेनिस

@ डेनिस तो समाधान 20 मनमानी लंबाई 1000 तार के साथ उचित समय में चलाने में सक्षम नहीं होना चाहिए?
टायरो

जवाबों:


4

सीजेएम, 31

q~L{_:&\f{_2$f#:).>j+}{,}$W>s}j

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

9 बाइट्स ने डेनिस को धन्यवाद दिया!

स्पष्टीकरण:

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

q~          read and evaluate the input (taken as an array)
L{…}j       execute block with recursive memoization and no starting values
  _         duplicate the array of strings
  :&\       intersect the strings as character sets and move before the array
             these are all the possible characters for the sequence
  f{…}      for each character and the array
    _2$     duplicate the array and the character
    f#      find the character position in each string
    :)      increment the positions (to skip the character)
    .>      slice each string starting at the corresponding position
    j       call the j block recursively
    +       concatenate the starting character with the result
  {,}$      sort resulting strings (one for each character) by length
  W>        keep only the last element, if any
  s         convert (from 0/1-string array) to string

5

अजगर - 665 644

संकेत स्तर:

1: space
2: tab
3: tab + space
4: 2 tabs
5: 2 tabs + space

कोड एक फ़ंक्शन को परिभाषित करता है o, जो तर्कों के रूप में स्ट्रिंग्स की एक सूची लेता है और स्ट्रिंग्स के लिए एलसीएस में से एक को वापस करता है।

def o(t):
 t=[[y for y in x if y in reduce(lambda x,y:x.intersection(y),t,set(t[0]))]for x in t];l=map(len,t);C=[0]*reduce(lambda x,y:x*-~y,l,1);y=lambda z:[x-1for x in z];m=len(t);e=enumerate
 def g(h):
    r,x=0,1
    for k,j in e(h):r+=-~j*x;x*=-~l[k]
    return r
 def f(h):
    i=len(h)
    if i==m:
     b=g(h);c=t[0][h[0]]
     for k,j in e(h):
         if t[k][j]!=c:break
     else:C[b]=1+C[g(y(h))];return
     r=0
     for k,_ in e(h):a=h[:];a[k]-=1;r=max(r,C[g(a)])
     C[b]=r;return
    for j,_ in e(t[i]):f(h+[j])
 def p(h):
    if min(h)==-1:return''
    v=C[g(h)]
    for k,_ in e(h):
        a=h[:];a[k]-=1
        if v==C[g(a)]:return p(a)
    return p(y(h))+t[0][h[0]]
 f([]);return p(y(l))

टेस्ट कोड:

tests = [
"""
a
ab
""",
"""
aaaaxbbbb
bbbbxcccc
ccccxaaaa
""",
"""
hxbecqibzpyqhosszypghkdddykjfjcajnwfmtfhqcpavqrtoipocijrmqpgzoufkjkyurczxuhkcpehbhpsuieqgjcepuhbpronmlrcgvipvibhuyqndbjbrrzpqbdegmqgjliclcgahxoouqxqpujsyfwbdthteidvigudsuoznykkzskspjufgkhaxorbrdvgodlb
qnnprxqpnafnhekcxljyysobbpyhynvolgtrntqtjpxpchqwgtkpxxvmwwcohxplsailheuzhkbtayvmxnttycdkbdvryjkfhshulptkuarqwuidrnjsydftsyhuueebnrjvkfvhqmyrclehcwethsqzcyfvyohzskvgttggndmdvdgollryqoswviqurrqhiqrqtyrl
""",
"""
riikscwpvsbxrvkpymvbbpmwclizxlhihiubycxmxwviuajdzoonjpkgiuiulbjdpkztsqznhbjhymwzkutmkkkhirryabricvhb
jnrzutfnbqhbaueicsvltalvqoorafnadevojjcsnlftoskhntashydksoheydbeuwlswdzivxnvcrxbgxmquvdnfairsppodznm
kzimnldhqklxyezcuyjaiasaeslicegmnwfavllanoolkhvqkjdvxrsjapqqwnrplcwqginwinktxnkfcuuvoyntrqwwucarfvjg
""",
"""
rblartqkfggrjpiipuzzypkycnyckkcqceeujiyy
yfpnedyjtiwrhyuktripdwyvgkblzodeufkelhub
ywcyboxwqkibwvredkrbdsyudkulpvmhixeqxynh
bnxwahbzhwjxkotnvbxrojkkldtsodtjmvdrmbgr
""",
"""
bwfscmotshoczmduwaev
coywaaizdaxjovipsmeh
dobzcpoiedenzlfdjpiu
bbhfeqscvvbwkuoxdoge
drqrzwbcpcsvneodelja
""",
"""
nqrualgoedlf
jgqorzglfnpa
fgttvnogldfx
pgostsulyfug
sgnhoyjlnfvr
wdttgkolfkbt
""",
"""
epopyfuhgowedpiqpgfj
ddxyestqynpwmytxhozm
ptubgzyqqksieoovuezv
tovotqmnhgzttfpywjgr
aomvytkgaijlgqzkljls
vzvxpaixrnprxvenbbuo
syfuwxlpcyontqlmfvib
arxleuomstkjegpduwcx
xgqrxaopouvkvwgbzewn
yggunddigctgpnuztzai
izroomywwztdymqszsuo
kiawjnxjncdtufhkrjsp
"""
]

for s in tests:
 print o(s.strip().split())

मेरे कंप्यूटर पर परीक्षण चलाने में समय लगता है:

$ time python 52808-shortest-longest-common-subsequence-code-golfed.py
a
x
hecbpyhogntqtpcqgkxchpsieuhbncvhuqndbjqmclchqyfhtdvgoysuhrrl
icsvllvanlktywuar
krkk
code
golf

        9.03 real         8.99 user         0.03 sys

1
आपको अपना कोड 666 बाइट्स में लाने के लिए एक बाइट जोड़ना चाहिए। तो धातु। \ m /
एलेक्स ए।

@AlexA। हाँ, मैंने यह भी देखा कि जब बाइट्स की गिनती की जाती है, तो इसमें अंतिम पंक्ति में एक नई रेखा शामिल होती है।
टायरो

कुछ छोटे सुधार हैं जिन्हें मैं अभी देख रहा हूं जो मदद करने चाहिए। सबसे पहले, कहीं भी आपके पास एक है (n+1), आप इसे -~nप्रत्येक मामले में 2 बाइट्स को बचाने के साथ बदल सकते हैं । इसके अलावा, कहीं भी आप के mapसाथ उपयोग करते हैं lambda, इसके बजाय सूची समझ का उपयोग करने पर विचार करें। उदाहरण के लिए, map(lambda x:x-1,z)इसे बदलकर तीन बाइट्स से छोटा किया जा सकता है [~-x for x in z]
केड

r,x=r+(j+1)*x,x*(l[k]+1)को छोटा किया जा सकता है r+=(j+1)*x;x*=(l[k]+1)। इसके अलावा, आप की जरूरत नहीं है u=...क्योंकि uकेवल एक ही स्थान पर उपयोग किया जाता है। बस उस कोड को अक्षर के लिए स्थानापन्न करें u
mbomb007

@ Vioz- और mbomb007 धन्यवाद।
टिलो

4

पायथ, 59 58 55 35 बाइट्स

L&@Fb?+yPMbeeb@FeMbeolNmyXJbdP@bdlb

@ लिसाकग के लिए धन्यवाद 20 बाइट्स काटें!

55 बाइट संस्करण:

DCHR?k!&.AH@FH?+Cm<1dHeeHql{medH1h.MlZ.eC++<Hk]<1b>HhkH

(गुना ऑपरेटर) .U@bZको बदलकर 3 बाइट्स काट लें @F

58 बाइट संस्करण:

DCHR?k!&.AH.U@bZH?+Cm<1dHeeHql{medH1h.MlZ.eC++<Hk]<1b>HhkH

एक बूलियन सशर्त के प्रारूप को बदलकर एक बाइट काट लें।

59 बाइट संस्करण:

DCHR?k|!.AH!.U@bZH?+Cm<1dHeeHql{medH1h.MlZ.eC++<Hk]<1b>HhkH

यह कठिन था! अजगर ने रखा सिगफॉल्टिंग! बहुत यकीन है कि यह किसी प्रकार का बग था, लेकिन मुझे एक न्यूनतम परीक्षण मामला नहीं मिला। ओह अच्छा।

मैं इस एक के एल्गोरिथ्म के आधार पर । जो ठीक है, सिवाय इसके कि एक को केवल दो तारों के लिए डिज़ाइन किया गया है। इसे और अधिक बनाने के लिए मुझे इसे थोड़ा मोड़ना पड़ा। फिर, अंतिम परीक्षण का मामला बहुत लंबा लग रहा था, इसलिए मुझे पुनरावृत्ति से बाहर निकलने के लिए एक अतिरिक्त जांच जोड़ना पड़ा अगर कोई अधिक सामान्य वर्ण नहीं हैं।

यह बहुत धीमी है, लेकिन चाहिए एक घंटे (उम्मीद) से भी कम समय ले लो। मैं 6 जीबी रैम के साथ अपने कोर i3 पर परीक्षण कर रहा हूं, इसलिए आपके 16-जीबी कोर i7 को इसके माध्यम से उड़ाना चाहिए। :)

मैंने इसे थोड़ा तेज करने के लिए पायथ के ऑटो-मेमोइजिंग कार्यों का भी लाभ उठाया।

संपादित करें : @ डेनिस ने कहा कि यह गुजरता है!

इसका परीक्षण करने के लिए, निम्नलिखित पंक्ति जोड़ें:

CQ

और इसे मानक इनपुट (जैसे ['a', 'ab']) के माध्यम से तार की एक सूची दें ।

35 बाइट संस्करण के लिए स्पष्टीकरण:

विप।

55 बाइट संस्करण के लिए स्पष्टीकरण:

DCH                                                        define a function C that takes a list of strings H
   R                                                       return the following expression
    ?                                                      if
      !&.AH@FH                                             there are no more common letters OR all the strings are empty
     k                                                     return the empty string
              ?          ql{medH1                          else if the last character of every string is equal
               +Cm<1dHeeH                                  return the result of adding the last character to recursion with every item without its last character
                                 h.MlZ.eC++<Hk]<1b>HhkH    otherwise, return the largest result of recursing len(H) times, each time with one element's last character cut off

@ डेनिस ओके; मैं इस पर काम करूंगा।
kirbyfan64sos

@ डेनिस अपडेट किया गया। अब आप फिर से कोशिश कर सकते हैं
kirbyfan64sos

अंतिम परीक्षण केस अब तुरंत समाप्त हो गया है।
डेनिस

@ डेनिस येस !!
kirbyfan64sos

@ kirbyfan64sos segfaults के बारे में: जब पुनरावृत्ति की गहराई बहुत अधिक बढ़ जाती है, जैसे कि अनंत पुनरावर्तन।
isaacg

4

सी, 618 564 बाइट्स

d,M,N,A[9999][2];char*(R[9999][20]),b[1000];L(char**s,n){char*j[20],c,a=0;int x[n],y=n-1,z,i,t,m=0,w=1;for(;y;)x[y--]=999;for(;y<N;y++){for(i=0;i<n&&s[i]==R[y][i];i++);if(i/n){a=A[y][0];m=A[y][1];w=0;if(m+d<M||!a)goto J;else{c=a;goto K;}}}for(c=97;w&&c<'{';c++){K:t=1,y=1,z=1;for(i=0;i<n;j[i++]++){for(j[i]=s[i];*j[i]-c;j[i]++)t&=!!*j[i];y&=j[i]-s[i]>x[i]?z=0,1:0;}t&=!y;I:if(t){if(z)for(i=0;i<n;i++)x[i]=j[i]-s[i];d++,t+=L(j,n),d--,m=t>m?a=c,t:m;}}if(w){for(y=0;y<n;y++)R[N][y]=s[y];A[N][0]=a;A[N++][1]=m;}J:if(d+m>=M)M=d+m,b[d]=a;if(!d)N=0,M=0,puts(b);return m;}

और यहाँ यह "पठनीयता" के लिए अप्रकाशित है:

d,M,N,A[9999][2];
char*(R[9999][20]),b[1000];
L(char**s,n){
    char*j[20],c,a=0;
    int x[n],y=n-1,z,i,t,m=0,w=1;
    for(;y;)
        x[y--]=999;
    for(;y<N;y++){
        for(i=0;i<n&&s[i]==R[y][i];i++);
        if(i/n){
            a=A[y][0];
            m=A[y][1];
            w=0;
            if(m+d<M||!a)
                goto J;
            else{
                c=a;
                goto K;
            }
        }
    }
    for(c=97;w&&c<'{';c++){
        K:
        t=1,
        y=1,
        z=1;
        for(i=0;i<n;j[i++]++){
            for(j[i]=s[i];*j[i]-c;j[i]++)
                t&=!!*j[i];
            y&=j[i]-s[i]>x[i]?z=0,1:0;
        }
        t&=!y;
        I:
        if(t){
            if(z)
                for(i=0;i<n;i++)
                    x[i]=j[i]-s[i];
            d++,
            t+=L(j,n),
            d--,
            m=t>m?a=c,t:m;
        }
    }
    if(w){
        for(y=0;y<n;y++)R[N][y]=s[y];
        A[N][0]=a;
        A[N++][1]=m;
    }
    J:
    if(d+m>=M)
        M=d+m,b[d]=a;
    if(!d)
        N=0,M=0,puts(b);
    return m;
}

देवियों और सज्जनों, मैंने एक भयानक गलती की है। यह प्रयोग किया जाता है खूबसूरत होने के लिए ... और गोटो कम ... अब कम से कम यह है तेजी से

हम एक पुनरावर्ती फ़ंक्शन को परिभाषित करते हैं Lजो इनपुट sके वर्णों की एक सरणी और nस्ट्रिंग की संख्या के रूप में लेता है । फ़ंक्शन परिणामी स्ट्रिंग को स्टडआउट करने के लिए आउटपुट करता है, और संयोग से उस स्ट्रिंग के पात्रों में आकार देता है।

पहुंच

हालाँकि यह कोड जटिल है, लेकिन यहां रणनीति बहुत जटिल नहीं है। हम एक बल्कि भोली पुनरावर्ती एल्गोरिथ्म के साथ शुरू करते हैं, जिसे मैं छद्मकोड के साथ वर्णित करूंगा:

Function L (array of strings s, number of strings n), returns length:

Create array of strings j of size n;

For each character c in "a-z",
    For each integer i less than n,
         Set the i'th string of j to the i'th string of s, starting at the first appearance of c in s[i]. (e.g. j[i][0] == c)
         If c does not occur in the i'th string of s, continue on to the next c.
    end For

    new_length := L( j, n ) + 1; // (C) t = new_length
    if new_length > best_length
        best_character := c; // (C) a = best_character
        best_length := new_length; // (C) m = best_length
    end if
end For

// (C) d = current_depth_in_recursion_tree
if best_length + current_depth_in_recursion_tree >= best_found
     prepend best_character to output_string // (C) b = output_string
     // (C) M = best_found, which represents the longest common substring found at any given point in the execution.
     best_found = best_length + current_depth;
end if

if current_depth_in_recursion_tree == 0
    reset all variables, print output_string
end if 

return best_length

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

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

  • हर बार जब हम के स्थान ढूंढने cमें s, इस बात की संभावना है कि हम सही बल्ले से दूर जानते हैं कि क्या हमने पाया है इष्टतम नहीं है। यदि प्रत्येक स्थान किसी अन्य पत्र के कुछ ज्ञात स्थान के बादc दिखाई देता है, तो हम स्वचालित रूप से जानते हैं कि इससे एक इष्टतम विकल्प नहीं बनता है, क्योंकि आप इसमें एक और अक्षर फिट कर सकते हैं। इसका मतलब है कि एक छोटी सी लागत के लिए, हम संभावित रूप से बड़े तार के लिए कई सौ कॉल निकाल सकते हैं। उपरोक्त सी कोड में, एक ध्वज सेट है यदि हम स्वचालित रूप से जानते हैं कि यह चरित्र एक सबॉप्टिमल स्ट्रिंग की ओर जाता है, और एक ध्वज सेट है यदि हमें एक ऐसा चरित्र मिलता है जो किसी अन्य ज्ञात चरित्र की तुलना में विशेष रूप से पहले दिखाई देता है। वर्णों की वर्तमान प्रारंभिक अभिव्यक्तियों को संग्रहीत किया जाता हैcLyzx। इस विचार का वर्तमान कार्यान्वयन थोड़ा गड़बड़ है, लेकिन कई उदाहरणों में लगभग दोगुना है।

इन दो विचारों के साथ, एक घंटे में खत्म नहीं हुआ अब लगभग 0.015 सेकंड लग गए।

संभवतः बहुत अधिक छोटी चालें हैं जो प्रदर्शन को गति दे सकती हैं, लेकिन इस बिंदु पर मुझे सब कुछ गोल्फ की अपनी क्षमता के बारे में चिंता करना शुरू कर दिया। मैं अभी भी गोल्फ से संतुष्ट नहीं हूँ, इसलिए मैं बाद में इस पर वापस आऊंगा!

समय

यहां कुछ परीक्षण कोड दिए गए हैं, जिन्हें मैं आपको ऑनलाइन प्रयास करने के लिए आमंत्रित करता हूं :

#include "stdio.h"
#include "time.h"

#define SIZE_ARRAY(x) (sizeof(x) / sizeof(*x))

int main(int argc, char** argv) {
    /* Our test case */
    char* test7[] = {
        "nqrualgoedlf",
        "jgqorzglfnpa",
        "fgttvnogldfx",
        "pgostsulyfug",
        "sgnhoyjlnfvr",
        "wdttgkolfkbt"
    };

    printf("Test 7:\n\t");
    clock_t start = clock();

    /* The call to L */
    int size = L(test7, SIZE_ARRAY(test7));


    double dt = ((double)(clock() - start)) / CLOCKS_PER_SEC;
    printf("\tSize: %d\n", size);
    printf("\tElapsed time: %lf s\n", dt);

    return 0;
}

मैंने एक ऑप्टिमाइज़ेशन सेटिंग के साथ 1.7 गीगाहर्ट्ज इंटेल कोर आई 7 चिप से लैस लैपटॉप पर ओपी के परीक्षण के मामलों को चलाया -Ofast। सिमुलेशन ने 712KB के एक शिखर की आवश्यकता की सूचना दी। यहाँ प्रत्येक परीक्षण मामले का एक उदाहरण रन है, समय के साथ:

Test 1:
    a
    Size: 1
    Elapsed time: 0.000020 s
Test 2:
    x
    Size: 1
    Elapsed time: 0.000017 s
Test 3:
    hecbpyhogntqppcqgkxchpsieuhbmcbhuqdjbrqmclchqyfhtdvdoysuhrrl
    Size: 60
    Elapsed time: 0.054547 s
Test 4:
    ihicvaoodsnktkrar
    Size: 17
    Elapsed time: 0.007459 s
Test 5:
    krkk
    Size: 4
    Elapsed time: 0.000051 s
Test 6:
    code
    Size: 4
    Elapsed time: 0.000045 s
Test 7:
    golf
    Size: 4
    Elapsed time: 0.000040 s
Test 8:

    Size: 0
    Elapsed time: 0.000029 s


Total time: 0.062293 s

गोल्फिंग में, मैंने प्रदर्शन को काफी प्रभावित किया, और जब से लोगों को मेरे पिछले 618-बाइट समाधान के ब्रूट गति (0.013624 के सभी परीक्षण मामलों को संयुक्त रूप से पूरा करना) पसंद आया, मैं इसे संदर्भ के लिए यहां छोड़ दूंगा:

d,M,N,A[9999][2];char*(R[9999][20]),b[1000];L(char**s,n){char*j[20],c,a=0;int x[n],y,z,i,t,m=0,w=1;for(y=0;y<n;y++)x[y]=999;for(y=0;y<N;y++){for(i=0;i<n;i++)if(s[i]!=R[y][i])break;if(i==n){a=A[y][0];m=A[y][1];w=0;if(m+d<M||!a)goto J;else{c=a;goto K;}}}for(c=97;w&&c<'{';c++){K:t=1,y=1,z=1;for(i=0;i<n;j[i++]++){for(j[i]=s[i];*j[i]-c;j[i]++)if(!*j[i]){t=0;goto I;}if(j[i]-s[i]>x[i])z=0;if(j[i]-s[i]<x[i])y=0;}if(y){t=0;}I:if(t){if(z){for(i=0;i<n;i++){x[i]=j[i]-s[i];}}d++,t+=L(j,n),d--,m=t>m?(a=c),t:m;}}if(w){for(y=0;y<n;y++)R[N][y]=s[y];A[N][0]=a;A[N++][1]=m;}J:if(d+m>=M)M=d+m,b[d]=a;if(!d)N=0,M=0,puts(b);return m;}

एल्गोरिथ्म स्वयं अपरिवर्तित है, लेकिन नया कोड डिवीजनों और कुछ पेचीदा बिटवाइज़ ऑपरेशनों पर निर्भर करता है जो अंत में पूरी चीज़ को धीमा कर देते हैं।


मैं एक समान विषय के बारे में सबसे तेज़-कोड चुनौती पोस्ट करने के बारे में सोच रहा था, लेकिन ऐसा लगता है कि मुझे अब और नहीं करना है। 0.01s और 712KB सिर्फ आश्चर्यजनक है।
डेनिस

यह बस आश्चर्यजनक है!
kirbyfan64sos

आपके स्पष्टीकरण को देखते हुए, बिल्ली क्या है best_found? यह केवल दो बार उल्लेख किया गया है, एक बार जब यह सशर्त में उपयोग किया जाता है, और दूसरा जब इसे रीसेट किया जाता है।
kirbyfan64sos

C स्रोत को देखते हुए, ऐसा लगता है कि best_foundसेट है best_length + current_depth। आपको स्पष्टीकरण में शायद इसका उल्लेख करना चाहिए!
kirbyfan64sos

@ kirbyfan64sos best_foundएक वैश्विक पूर्णांक है जो निष्पादन में किसी भी बिंदु पर पाए जाने वाले सबसे लंबे सामान्य प्रतिस्थापन की लंबाई का वर्णन करता है। मैं स्पष्टीकरण में डालूँगा!
ब्रेनसैट

1

पायथन 2, 285

कोड:

import re
def f(s,a,b):
  if b==[]:return s+f('',[],a)
  if a==[]:return s+max([f(b[0][i],[b[0][i+1:]],b[1:]) for i in range(len(b[0]))],key=len) if b[0]!='' else ''
  return max([f(s,a+[b[0][i.start()+1:]],b[1:]) for i in re.finditer(s[-1],b[0])],key=len) if ~b[0].find(s[-1]) else ''

उपयोग:

print f('',[],['axbycz','xaybzc'])

स्पष्टीकरण:

यह एक पुनरावर्ती कार्य है। sहम जिस चरित्र की तलाश कर रहे हैं। aबाद कटा हुआ तार की सूची है sbइसमें अभी तक छुआछूत के तार शामिल हैं। fसबसे लंबी सामान्य स्ट्रिंग लौटाता है।

पहली शर्त यह जांचती है कि क्या हम सभी तारों से गुजरना खत्म कर चुके हैं। यदि ऐसा है, तो इसका मतलब है sकि सामान्य चरित्र है, और यह लौटता है sऔर अधिक सामान्य पात्रों की तलाश करता है।

दूसरी स्थिति यह जांचती है कि क्या हम किसी तार से गुजरना शुरू नहीं करते हैं, जिसका अर्थ है कि हमारा चरित्र भी नहीं है ( a==[]बराबर है s=='')। यदि ऐसा है तो हम पहले स्ट्रिंग के प्रत्येक चरित्र की जाँच करते हैं b

अंतिम पंक्ति में पहली स्ट्रिंग ले जाता है bकरने के लिए a, में से प्रत्येक घटना का पता लगाकर sइस स्ट्रिंग में।

पहली कॉल पर, sखाली स्ट्रिंग होना चाहिए। aखाली सूची bहोनी चाहिए और इसमें सभी तार शामिल होने चाहिए।


2
आपको डिफ़ॉल्ट तर्कों का उपयोग करना चाहिए ताकि फ़ंक्शन को केवल तार की आवश्यकता हो, जैसे f(b,s='',a=[])
feersum
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.