Bash Perl, 231 229 218 178 164 166 138 106 74 bytes
/^(((.*).*)\2+)\3$/;$_.=$1x2;$.--,die$+[1]if/^(.*)(.)(.*)
.*\1(?!\2).\3/
The script requires using the -n
switch, which accounts for two of the bytes.
The idea of appending two copies of all full repetitions of the pattern has been taken from MT0's answer.
In contrast to all other answers, this approach attempts to extract the pattern of the current input line in each iteration; it will fail on the line containing the odd character (and use the pattern of the previous line instead). This is done to include the pattern extraction in the loop, which manages to save a few bytes.
Ungolfed version
#!/usr/bin/perl -n
# The `-n' switch makes Perl execute the entire script once for each input line, just like
# wrapping `while(<>){…}' around the script would do.
/^(((.*).*)\2+)\3$/;
# This regular expression matches if `((.*).*)' - accessible via the backreference `\2' -
# is repeated at least once, followed by a single repetition of `\3" - zero or more of the
# leftmost characters of `\2' - followed by the end of line. This means `\1' will contain
# all full repetitions of the pattern. Even in the next loop, the contents of `\1' will be
# available in the variable `$1'.
$_.=$1x2;
# Append two copies of `$1' to the current line. For the line, containing the odd
# character, the regular expression will not have matched and the pattern of the previous
# line will get appended.
#
# Since the pattern is repeated at least two full times, the partial pattern repetition at
# the end of the previous line will be shorter than the string before it. This means that
# the entire line will the shorter than 1.5 times the full repetitions of the pattern,
# making the two copies of the full repetitions of the pattern at least three times as
# long as the input lines.
$.-- , die $+[1] if
# If the regular expression below matches, do the following:
#
# 1. Decrement the variable `$.', which contains the input line number.
#
# This is done to obtain zero-based coordinates.
#
# 2. Print `$+[1]' - the position of the last character of the first subpattern of the
# regular expression - plus some additional information to STDERR and exit.
#
# Notably, `die' prints the (decremented) current line number.
/^(.*)(.)(.*)
.*\1(?!\2).\3/;
# `(.*)(.)(.*)', enclosed by `^' and a newline, divides the current input line into three
# parts, which will be accesible via the backreferences `\1' to `\3'. Note that `\2'
# contains a single character.
#
# `.*\1(?!\2).\3' matches the current input line, except for the single character between
# `\1' and `\3' which has to be different from that in `\2', at any position of the line
# containing the pattern repetitions. Since this line is at least thrice as long as
# `\1(?!\2).\3', it will be matched regardless of by how many characters the line has been
# rotated.
Example
For the test case
codegolfcodegolfco
egolfcodegolfcodeg
lfcodegolfcodegoff
odegolfcodegolfcod
golfcodegolfcodego
fcodegolfcodegolfc
the output of the golfed version is
16 at script.pl line 1, <> line 2.
meaning that the odd character has the coordinates 16,2
.
This blatantly abuses takes advantage of the liberal output format.
Just before exiting, the contents of some of Perl's special variables are:
$_ = lfcodegolfcodegoff\ncodegolfcodegolfcodegolfcodegolf
$1 = lfcodegolfcodego
$2 = f
$3 = f
($n
contains the match of the subpattern accessible via the backreference \n
.)
abc/cab/abc
- and output0 2
here? \$\endgroup\$