রৈখিক সময়ে সর্বাধিক দীর্ঘতম স্ট্রাস্টিং


45

এই চ্যালেঞ্জটি নিম্নলিখিত সমস্যাটি সমাধান করার জন্য কোড লেখার বিষয়ে।

দুটি এবং দুটি স্ট্রিং দেওয়া আপনার কোডের নীচের বৈশিষ্ট্যগুলির সাথে A এর স্ট্রিংয়ের শুরু এবং শেষ সূচকগুলি আউটপুট করা উচিত।

  • এ এর স্ট্রিংগুলি বি এর কিছু স্ট্রিংয়ের সাথেও মেলে should
  • প্রথম সম্পত্তি সন্তুষ্ট করে এমন আর আর সাবস্ট্রিং থাকা উচিত নয়।

উদাহরণ স্বরূপ:

A = xxxappleyyyyyyy

B = zapplezzz

appleসূচকের সাথে সাবস্ট্রিং 4 8(1 থেকে সূচিককরণ) একটি বৈধ আউটপুট হবে।

কার্যকারিতার

আপনি ধরে নিতে পারেন ইনপুটটি স্থানীয় ডিরেক্টরিতে কোনও ফাইলে বা কোনও ফাইলে থাকবে, এটি আপনার পছন্দ। ফাইল ফর্ম্যাটটি কেবল দুটি স্ট্রিং হবে, একটি নতুন লাইনের দ্বারা পৃথক। উত্তরটি কেবল একটি ফাংশন নয়, একটি পূর্ণ প্রোগ্রাম হওয়া উচিত।

অবশেষে http://hgdownload.cse.ucsc.edu/goldenPath/hg38/chromosomes/ এ স্ট্রিং থেকে নেওয়া দুটি সাবস্ট্রিংয়ে আপনার কোডটি পরীক্ষা করতে চাই ।

স্কোর

এটি একটি মোচড় সহ কোড-গল্ফ। আপনার কোডটি O(n)সময়মতো চালানো উচিত , যেখানে nইনপুটটির মোট দৈর্ঘ্য।

ভাষা ও গ্রন্থাগার

আপনি যে কোনও ভাষা নিখরচায় উপলব্ধ সংকলক / দোভাষী / ইত্যাদি ব্যবহার করতে পারেন। লিনাক্সের জন্য। আপনার কেবল এই স্ট্যান্ডার্ড ওপেন সোর্স লাইব্রেরি ব্যবহার করা উচিত যা এই কার্যটি সমাধান করার জন্য নয়। বিরোধের ক্ষেত্রে, আমি এটি এমন কোনও লাইব্রেরি হিসাবে গণনা করব যা হয় আপনার ভাষার সাথে মান হিসাবে আসে বা একটি ডিফল্ট সংগ্রহশালা থেকে আপনি একটি ডিফল্ট উবুন্টু মেশিনে ইনস্টল করতে পারেন।

দরকারী তথ্য

রৈখিক সময়ে এই সমস্যাটি সমাধান করার জন্য কমপক্ষে দুটি উপায় রয়েছে। একটি হ'ল প্রথমে প্রত্যয় গাছ এবং দ্বিতীয়টি প্রথমে প্রত্যয় অ্যারে এবং এলসিপি অ্যারে গণনা করা।


4
O(n) timeআপনি কি নিশ্চিত যে এটি সম্ভব?
সাভেনকভ আলেক্সি

17
@ ল্যাম্বিক দুঃখিত, তবে এগুলি অত্যন্ত জটিল অ্যালগরিদম এবং 100+ লাইন কোডের গল্ভ করা সত্যিই মজাদার নয়।
FUZxxl

4
"দরকারী তথ্য" এর অধীনে আপনি যে দ্বিতীয় লিঙ্কটি সরবরাহ করেছেন তার নিবন্ধটি বলেছে যে "[প্রত্যয় গাছ] নির্মাণের জন্য ও (এন ^ 2) সময় প্রয়োজন"
কেএসএফটি

3
@ ল্যাম্বিক আপনার কেবল প্রশ্নটি করা উচিত [দ্রুততম কোড] যেখানে বিগ-ওহ স্বরলিপিতে সবচেয়ে খারাপ ক্ষেত্রে মামলাটি জিততে পারে। তারপরে আপনি কমপক্ষে কিছু উত্তর পেয়ে যাবেন এবং এমনকি কেউ (ও) এ এটি সমাধান করতে পারে এমনকী তারা জিতবে।
mbomb007

9
বৈধ উত্তরের জন্য সর্বাধিক মুছে ফেলা উত্তরগুলির সাথে এটি অবশ্যই প্রশ্ন হওয়া উচিত ...
ফ্লিপট্যাক

উত্তর:


39

পাইথন 2, 646 বাইট

G=range;w=raw_input;z=L,m,h=[0]*3
s=w();t=len(s);s+='!%s#'%w();u=len(s);I=z*u
def f(s,n):
 def r(o):
    b=[[]for _ in s];c=[]
    for x in B[:N]:b[s[x+o]]+=x,
    map(c.extend,b);B[:N]=c
 M=N=n--~n/3;t=n%3%2;B=G(n+t);del B[::3];r(2);u=m=p=r(1)>r(0);N-=n/3
 for x in B*1:v=s[x:x+3];m+=u<v;u=v;B[x/3+x%3/2*N]=m
 A=1/M*z or f(B+z,M)+z;B=[x*3for x in A if x<N];J=I[r(0):n];C=G(n)
 for k in C:b=A[t]/N;a=i,j=A[t]%N*3-~b,B[p];q=p<N<(s[i:i-~b],J[i/3+b+N-b*N])>(s[j+t/M:j-~b],J[j/3+b*N]);C[k]=x=a[q];I[x]=k;p+=q;t+=1-q
 return C
S=f(map(ord,s)+z*40,u)
for i in G(u):
 h-=h>0;j=S[I[i]-1]
 while s[i+h]==s[j+h]:h+=1
 if(i<t)==(t<j)<=h>m:m=h;L=min(i,j)
print-~L,L+m

এটি কার্ক্কেসিনেন এবং স্যান্ডার্সের "সিম্পল লিনিয়ার ওয়ার্ক প্রত্যয় অ্যারে নির্মাণ" -এ বর্ণিত স্কিউ অ্যালগরিদম ব্যবহার করে। সেই কাগজে অন্তর্ভুক্ত সি ++ বাস্তবায়ন ইতিমধ্যে কিছুটা "গল্ফ" লাগছে, তবে এটি আরও খাটো করার জন্য এখনও প্রচুর জায়গা রয়েছে। উদাহরণস্বরূপ, O(n)প্রয়োজনীয়তা লঙ্ঘন না করে আমরা কাগজের মতো শর্ট সার্কিটের পরিবর্তে দৈর্ঘ্যের একটি অ্যারে না পৌঁছানো পর্যন্ত পুনরাবৃত্তি করতে পারি ।

এলসিপি অংশের জন্য, আমি কুসাই এট আল দ্বারা "সূফিক অ্যারে এবং এর অ্যাপ্লিকেশনগুলিতে লিনিয়ার-টাইম দীর্ঘতম-সাধারণ-উপসর্গ গণনা" অনুসরণ করেছি।

1 0দীর্ঘতম সাধারণ স্ট্রিংটি খালি থাকলে প্রোগ্রামটি আউটপুট দেয়।

এখানে কিছু বিকাশ কোড যা প্রোগ্রামটির পূর্ববর্তী সংস্করণ অন্তর্ভুক্ত করে যা সি ++ বাস্তবায়নকে আরও ঘনিষ্ঠভাবে অনুসরণ করে, তুলনার জন্য কিছু ধীর পন্থা এবং একটি সাধারণ পরীক্ষার কেস জেনারেটর:

from random import *

def brute(a,b):
    L=R=m=0

    for i in range(len(a)):
        for j in range(i+m+1,len(a)+1):
            if a[i:j] in b:
                m=j-i
                L,R=i,j

    return L+1,R

def suffix_array_slow(s):
    S=[]
    for i in range(len(s)):
        S+=[(s[i:],i)]
    S.sort()
    return [x[1] for x in S]

def slow1(a,b):
    # slow suffix array, slow lcp

    s=a+'!'+b
    S=suffix_array_slow(s)

    L=R=m=0

    for i in range(1,len(S)):
        x=S[i-1]
        y=S[i]
        p=s[x:]+'#'
        q=s[y:]+'$'
        h=0
        while p[h]==q[h]:
            h+=1
        if h>m and len(a)==sorted([x,y,len(a)])[1]:
            m=h
            L=min(x,y)
            R=L+h

    return L+1,R

def verify(a,b,L,R):
    if L<1 or R>len(a) or a[L-1:R] not in b:
        return 0
    LL,RR=brute(a,b)
    return R-L==RR-LL

def rand_string():
    if randint(0,1):
        n=randint(0,8)
    else:
        n=randint(0,24)
    a='zyxwvutsrq'[:randint(1,10)]
    s=''
    for _ in range(n):
        s+=choice(a)
    return s

def stress_test(f):
    numtrials=2000
    for trial in range(numtrials):
        a=rand_string()
        b=rand_string()
        L,R=f(a,b)
        if not verify(a,b,L,R):
            LL,RR=brute(a,b)
            print 'failed on',(a,b)
            print 'expected:',LL,RR
            print 'actual:',L,R
            return
    print 'ok'

def slow2(a,b):
    # slow suffix array, linear lcp

    s=a+'!'+b+'#'
    S=suffix_array_slow(s)

    I=S*1
    for i in range(len(S)):
        I[S[i]]=i

    L=R=m=h=0

    for i in range(len(S)):
        if I[i]:
            j=S[I[i]-1]
            while s[i+h]==s[j+h]:
                h+=1
            if h>m and len(a)==sorted([i,j,len(a)])[1]:
                m=h
                L=min(i,j)
                R=L+h
            h-=h>0

    return L+1,R

def suffix_array(s,K):
    # skew algorithm

    n=len(s)
    s+=[0]*3
    n0=(n+2)/3
    n1=(n+1)/3
    n2=n/3
    n02=n0+n2
    adj=n0-n1

    def radix_pass(a,o,n=n02):
        c=[0]*(K+3)
        for x in a[:n]:
            c[s[x+o]+1]+=1
        for i in range(K+3):
            c[i]+=c[i-1]
        for x in a[:n]:
            j=s[x+o]
            a[c[j]]=x
            c[j]+=1

    A=[x for x in range(n+adj) if x%3]+[0]*3

    radix_pass(A,2)
    radix_pass(A,1)
    radix_pass(A,0)

    B=[0]*n02
    t=m=0

    for x in A[:n02]:
        u=s[x:x+3]
        m+=t<u
        t=u
        B[x/3+x%3/2*n0]=m

    A[:n02]=1/n02*[0]or suffix_array(B,m)
    I=A*1
    for i in range(n02):
        I[A[i]]=i+1

    B=[3*x for x in A if x<n0]
    radix_pass(B,0,n0)

    R=[]

    p=0
    t=adj
    while t<n02:
        x=A[t]
        b=x>=n0
        i=(x-b*n0)*3-~b
        j=B[p]
        if p==n0 or ((s[i:i+2],I[A[t]-n0+1])<(s[j:j+2],I[j/3+n0]) if b else (s[i],I[A[t]+n0])<(s[j],I[j/3])):R+=i,;t+=1
        else:R+=j,;p+=1

    return R+B[p:n0]

def solve(a,b):
    # linear

    s=a+'!'+b+'#'
    S=suffix_array(map(ord,s),128)

    I=S*1
    for i in range(len(S)):
        I[S[i]]=i

    L=R=m=h=0

    for i in range(len(S)):
        if I[i]:
            j=S[I[i]-1]
            while s[i+h]==s[j+h]:
                h+=1
            if h>m and len(a)==sorted([i,j,len(a)])[1]:
                m=h
                L=min(i,j)
                R=L+h
            h-=h>0

    return L+1,R

stress_test(solve)

1
আমি ভুল হলে আমাকে সংশোধন করুন, তবে এটি আসলে 739 বাইট নয়? আমি mothereff.in/byte-coutter এ অনুলিপি করেছিলাম এবং 6-9 লাইন থেকে 2 টি স্পেস মুছলাম , তবে আমি নিশ্চিত না যে এটি সঠিক কিনা।
প্যাট্রিক রবার্টস

2
পছন্দ করুন
মিচ শোয়ার্টজ

2
চমৎকার উত্তর! আপনি জিএসএসিএ-র একটি উপন্যাস লিনিয়ার টাইম এসএসিএ থেকে ২০১ from সালের দিকে নজর রাখতে চান Re আপনি এটি গিথুবে খুঁজে পাবেন।
ক্রিস্টোফ

1
@ মিচশওয়ার্টজ আমি বর্তমানে নোপোমোতে থাকার চেষ্টা করছি, তাই এখনই আবেগকে দৃ strongly়ভাবে অনুভব করতে পারি না (সম্ভবত ভারসাম্যহীন মস্তিষ্কের রাসায়নিকের কারণে)। কোডটি দ্রুত পড়ার সময়, আমার সিনট্যাক্স গল্ফিং মোটরটি স্পট করেছিল এবং কোনও নির্দিষ্ট আবেগ অনুভব করার কথা মনে নেই। আপনি কি একই জিনিস ভেবেছিলেন বা কেন প্রশ্ন? :) এখন আমি কৌতূহলী।
Yytsi

1
@ টুক্কাএক্স এটি একটি আকর্ষণীয় প্রতিক্রিয়া যা আমি আশা করি না। ঠিক আছে, আমি নিশ্চিত না যে আমাকে এটির বিশেষ কোনও উপায়ে শব্দ করা উচিত কিনা, তবে কেন আপনার জিজ্ঞাসা করার সিদ্ধান্ত নিয়েছিলাম তা আপনার মূল মন্তব্যটি সঠিক ছিল না some :)
মিচ শোয়ার্জ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.