note
tye
<p>
I assume that the pattern must repeat at least twice, otherwise, the full string is always the longest answer.
</p><p>
A simple regex can get a good guess and tell you when that guess has failed in such a way that each subsequent guess will be more than twice as long as the previous guess so the regex doesn't have to be run very many times:
</p><c>
sub repeating {
my( $string ) = @_;
my( $pattern, $repeat, $end ) = $string =~ /^(.+?)(\1+)(.*)$/;
while( defined $pattern ) {
return $pattern
if length($end) <= length($pattern)
&& $end eq substr($pattern,0,length($end));
print "($pattern) wasn't long enough.\n";
( $pattern, $repeat, $end ) =
$string =~ /^(\Q$pattern$repeat\E.+?)(\1+)(.*)$/
}
return undef;
}
my $pattern = repeating( "aabaabaabcaabaabaabca" );
printf "(%s) wins\n", $pattern
if $pattern;
__END__
(a) wasn't long enough.
(aab) wasn't long enough.
(aabaabaabc) wins
</c><p>
You likely can optimize this by copying less stuff, of course.
</p><p>
<b>(Update:</b> Well, I didn't get very rigorous in proving to myself that $pattern.$repeat is <em>always</em> too short. But I believe that to be the case. One should validate or refute that assumption before deciding whether to use this.<b>)</b>
</p>
<div class="pmsig"><div class="pmsig-22609"><p align="right">
- [tye]<tt> </tt>
</p></div></div>
1039630
1039630