# Find longest stretch of pattern from centre of sequence

How to calculate the longest consecutive pattern of C/T anywhere in sequence and longest consecutive pattern of C/T from centre

CCCCTGTTGCCAAACAATGC

TTTTCCCGCCTTTGGCCTAC

TACACGGAACCTCTTTTTTA

The desired output is to calculate the longest consecutive pattern of C/T anywhere in sequence and longest consecutive pattern of C/T from centre

CCCCTGTTGCCAAACAATGC 5 2

TTTTCCCGCCTTTGGCCTAC 7 5

TACACGGAACCTCTTTTTTA 10 10

The first line has 5 consecutive pattern of C/T in the sequence, while the longest C/T pattern from center is 2.

PS. A solution to similar question is here Count the longest stretch of consecutive patterns

• What do you mean by "from centre"? Du you mean only in the second half of the sequence? The first sequence does not contain a run two `C` or `T` in the second half. – Kusalananda Oct 15 '18 at 9:56

I assume you mean by "from center" is "the sequence that includes the middle character of the string. I've added a line to the testing data such that the middle character of the string is neither a C or a T:

``````\$ cat file
CCCCTGTTGCCAAACAATGC
TTTTCCCGCCTTTGGCCTAC
TACACGGAACCTCTTTTTTA
CATAAAAAAAAAAAAACTCT
``````

The solution relies on awk's RSTART and RLENGTH variables that are set as a by-product of the match() function matching the pattern, and some arithmetic to keep track of where we are in the string:

``````awk '{
line = \$0
max = max_ctr = 0
mid = int(length(\$0)/2)
idx = 1
while (match( substr(line,idx), /[CT]+/ )) {
if (RLENGTH > max) max = RLENGTH
if (idx <= mid && mid <= idx+RLENGTH) max_ctr = RLENGTH
idx += RSTART + RLENGTH - 1
}
print \$0, max, max_ctr
}' file
``````

outputs

``````CCCCTGTTGCCAAACAATGC 5 2
TTTTCCCGCCTTTGGCCTAC 7 5
TACACGGAACCTCTTTTTTA 10 10
CATAAAAAAAAAAAAACTCT 4 0
``````

In case "from centre" means "longest string closest to centre but not necessarily crossing it", you could try

``````awk '
{MID = int(length()/2);
MX = PTR = 0
T0 = \$0
while (match (\$0, /[CcTt]+/))  {if (RLENGTH > MX) MX = RLENGTH

SSTR = PTR  + RSTART
SEND = SSTR + RLENGTH - 1
TMPS = SSTR - MID
TMPE = MID  - SEND
if  (SEND < MID)                                       {P = TMPE; RES = RLENGTH}
else   {if (SSTR <= MID)                               {P = 0;    RES = RLENGTH}
else if ((P > TMPS) ||
(P == TMPS) && (RLENGTH >  RES))      {P = TMPS; RES = RLENGTH}
}
PTR  = SEND
\$0 = substr (\$0, RSTART + RLENGTH)
}
print T0, MX, RES
}
' file
``````

It loops through the line from regex to regex match, keeping a pointer to hold the position in original line. Hereby it counts character distance from string end to centre, or from centre to start of string, and assigns the smallest distance's string length to the result variable. For equal distance, it retains the longest length.

For patterns crossing the centre, the result is equivalent to the samples given before.