Python 2, 338 326 323 321 321 310 306 297 293 290 289 280 279 266 264 259 237 230 229 226 223 222 220 219 217 ( 260 238 231 228 225 2222 221 220 218 con 0 stato di uscita)
exec'''s=raw_input()
S=[M-s.rfind(c,0,M)for M,c in enumerate(s)]
k=0
j=x=%s
while k<=M+x:
if S[k]>j<W[j]or S[k]==W[j]:
k+=1;j+=1;T+=[j]
if j-L>x:print s[k-j:k];z
else:j=T[j]
'''*2%('-1;T=[0];W=S;L=M',0)
print'No!'
L'algoritmo è una variante di KMP, che utilizza un test basato sull'indice per la corrispondenza dei caratteri. L'idea di base è che se otteniamo una discrepanza nella posizione, X[i]possiamo tornare al prossimo posto possibile per una partita in base al suffisso più lungo X[:i]che è isomorfo a un prefisso di X.
Operando da sinistra a destra, assegniamo a ciascun carattere un indice pari alla distanza dall'occorrenza precedente più recente di quel carattere, oppure se non si verifica un'occorrenza precedente prendiamo la lunghezza del prefisso di stringa corrente. Per esempio:
MISSISSIPPI
12313213913
Per verificare se due caratteri corrispondono, confrontiamo gli indici, regolandoli in modo appropriato per gli indici che sono maggiori della lunghezza della (sotto) stringa corrente.
L'algoritmo KMP diventa un po 'semplificato poiché non è possibile ottenere una mancata corrispondenza con il primo carattere.
Questo programma genera la prima corrispondenza, se esiste. Uso un errore di runtime per uscire in caso di corrispondenza, ma il codice può essere facilmente modificato per uscire in modo pulito al costo di alcuni byte.
Nota: per gli indici di calcolo, possiamo usare str.rfind(al contrario del mio approccio precedente usando un dizionario) e avere comunque una complessità lineare, supponendo che str.rfindinizi la ricerca dalla fine (che sembra l'unica scelta di implementazione sensata) - per ogni carattere dell'alfabeto , non dobbiamo mai attraversare due volte la stessa parte della stringa, quindi esiste un limite superiore di confronti (dimensione dell'alfabeto) * (dimensione della stringa).
Poiché il codice è stato abbastanza offuscato nel corso del golf, ecco una soluzione precedente (293 byte) che è un po 'più facile da leggere:
e=lambda a:a>i<W[i]or a==W[i]
exec('s=raw_input();S=[];p={};M=i=0\nfor c in s:S+=[M-p.get(c,-1)];p[c]=M;M+=1\nW=S;L=M;'*2)[:-9]
T=[0]*L
k=1
while~k+L:
if e(W[k]):i+=1;k+=1;T[k]=i
else:i=T[i]
m=i=0
while m+i<M:
if e(S[m+i]):
if~-L==i:print s[m:m+L];z
i+=1
else:m+=i-T[i];i=T[i]
print'No!'
La efunzione verifica l'equivalenza dei caratteri. L' execistruzione assegna indici e fa alcune inizializzazioni variabili. Il primo ciclo elabora i Xvalori di fallback e il secondo ciclo esegue la ricerca di stringhe.
Aggiornamento: ecco una versione che esce in modo pulito, al costo di un byte:
r='No!'
exec'''s=raw_input()
S=[M-s.rfind(c,0,M)for M,c in enumerate(s)]
k=0
j=x=%s
while k<=M+x:
if S[k]>j<W[j]or S[k]==W[j]:
k+=1;j+=1;T+=[j]
if j-L>x:r=k=s[k-j:k]
else:j=T[j]
'''*2%('-1;T=[0];W=S;L=M',0)
print r