Python 2, 338 326 323 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 223 221 220 218 avec 0 statut de sortie)
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'algorithme est une variante de KMP, utilisant un test basé sur un index pour la correspondance des caractères. L'idée de base est que si nous obtenons un décalage à la position, X[i]nous pouvons retomber à l'endroit suivant possible pour une correspondance selon le suffixe le plus long X[:i]qui est isomorphe à un préfixe de X.
De gauche à droite, nous attribuons à chaque caractère un index égal à la distance à l'occurrence précédente la plus récente de ce caractère, ou s'il n'y a pas d'occurrence précédente, nous prenons la longueur du préfixe de chaîne actuel. Par exemple:
MISSISSIPPI
12313213913
Pour tester si deux caractères correspondent, nous comparons les indices en ajustant de manière appropriée les indices supérieurs à la longueur de la (sous-) chaîne actuelle.
L'algorithme KMP devient un peu simplifié car nous ne pouvons pas obtenir une différence sur le premier caractère.
Ce programme génère la première correspondance s'il en existe une. J'utilise une erreur d'exécution pour quitter en cas de correspondance, mais le code peut être facilement modifié pour quitter proprement au prix de quelques octets.
Remarque: Pour le calcul des indices, nous pouvons utiliser str.rfind(contrairement à mon approche précédente en utilisant un dictionnaire) et avoir toujours une complexité linéaire, en supposant que str.rfindcommence la recherche depuis la fin (ce qui semble être le seul choix d'implémentation sain) - pour chaque caractère de l'alphabet , nous n'avons jamais à parcourir deux fois la même partie de la chaîne, il y a donc une limite supérieure de comparaison (taille de l'alphabet) * (taille de la chaîne).
Étant donné que le code est devenu assez obscur au cours du golf, voici une solution antérieure (293 octets) qui est un peu plus facile à lire:
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 efonction teste l'équivalence des caractères. L' execinstruction assigne des indices et effectue quelques initialisations variables. La première boucle traite Xles valeurs de repli et la seconde boucle effectue la recherche de chaîne.
Mise à jour: voici une version qui se termine proprement, au prix d'un octet:
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