# 
# Grr, .5 can mean what I want in one place but not another... so 
# forcing integer arithmetic is better anyway:
# 

sub repeated_substring
{
  my $len = length($_[0]);

  my ($best, $bestlen) = ("", 0);

  my ($left, $leftlen, $rightpos, $skip, $optimizing);
  my $leftstart = 0;
  while ($leftstart <= $len - 2 * ($bestlen+1))
  {
    $rightpos = $leftstart + ($leftlen = 1 + $bestlen);
    $left = substr($_[0], $leftstart, $leftlen);

    while ($skip = 1)        # Triggers syntax warning 
    {
      if ($optimizing)
      {
	# If last half of substring at current position
	# isn't anywhere in rest of string, we can skip
	# to 1 past its beginning
	my $half = $bestlen >> 1;
	if (index($_[0], substr($left, $half, $half), $rightpos) < 0)
	{
	  $skip = $half + 1;
	  last;
	}
      }
      last unless ($rightpos = index($_[0], $left, $rightpos)) >= 0;

      if ($leftlen > $bestlen)
      {
	$best       = $left; 
	$bestlen    = $leftlen;
	$optimizing = $bestlen > 16;
      }
      $left = substr($_[0], $leftstart, ++$leftlen);

      $rightpos++ if $leftstart + $leftlen > $rightpos;  # Overlapping

      redo if index($_[0], $left, $rightpos) >= 0;

      $rightpos += $leftlen;
    }
    $leftstart += $skip;
  }
  return $best;
}

