Problem:
Score : 400 points

Problem Statement

We have a string S of length N consisting of R, G, and B.

Find the number of triples (i,~j,~k)~(1 \leq i < j < k \leq N) that satisfy both of the following conditions:

S_i \neq S_j, S_i \neq S_k, and S_j \neq S_k.

j - i \neq k - j.

Constraints

1 \leq N \leq 4000

S is a string of length N consisting of R, G, and B.

Input

Input is given from Standard Input in the following format:

N
S

Output

Print the number of triplets in question.

Sample Input 1

4
RRGB

Sample Output 1

1

Only the triplet (1,~3,~4) satisfies both conditions. The triplet (2,~3,~4) satisfies the first condition but not the second, so it does not count.

Sample Input 2

39
RBRBGRBGGBBRRGBBRRRBGGBRBGBRBGBRBBBGBBB

Sample Output 2

1800

Solution in Haskell (GHC 8.8.3) (judge verdict: Runtime Error)

module Main where

import           Control.Monad
import           Debug.Trace
import qualified Data.Vector                   as V
import qualified Data.Vector.Mutable           as VM
import qualified Data.Vector.Unboxed           as VU
import qualified Data.Vector.Unboxed.Mutable   as VUM
import           Data.List
import qualified Data.ByteString               as BS
import qualified Data.ByteString.Char8         as BSC8
import           Data.Char
import           Data.Maybe
import           Data.Ord
import           Data.Vector.Algorithms.Search
import qualified Data.Array                    as A
import qualified Data.Array.Unboxed            as AU
import qualified Data.Array.IO                 as AIO



getvuil :: IO (VU.Vector Int)
getvuil = VU.unfoldr (BSC8.readInt . BSC8.dropWhile isSpace) <$> BSC8.getLine
readi :: BSC8.ByteString -> Int
readi = fst . fromJust . BSC8.readInt
readil :: BSC8.ByteString -> [Int]
readil = map readi . BSC8.words
geti :: IO Int
geti = readi <$> BSC8.getLine
getil :: IO [Int]
getil = readil <$> BSC8.getLine

getNis :: Int -> IO [(Int, BSC8.ByteString)]
getNis 0 = return []
getisl n = do
    [aFst, aSnd] <- BSC8.words <$> BSC8.getLine
    next         <- (getisl (n - 1))
    return ((readi aFst, aSnd) : next)

il2ss :: [Int] -> String
il2ss = unwords . map show

il2sn :: [Int] -> String
il2sn = unlines . map show

main :: IO ()
main = do
    aN <- geti
    aS <- VU.fromList <$> getLine
    let lastC         = VU.last aS
    let lastLastI = searchLastLast aS (VU.length aS - 2) lastC
    let lastLastC     = aS VU.! lastLastI
    let lastLastLastI = searchLastLastLast aS lastLastI lastC lastLastC

    let
        ret = foldl
            (\acc1 x ->
                let
                    firstI = x
                    firstC = aS VU.! x
                in
                    acc1
                        + (foldl
                              (\acc2 y ->
                                  let
                                      secondI = y
                                      secondC = aS VU.! y
                                      thirdK  = seleK firstC secondC
                                  in
                                      if firstC == secondC
                                          then acc2
                                          else
                                              acc2
                                                  + (foldl
                                                        (\acc3 z ->
                                                            let thirdI = z
                                                                thirdC =
                                                                        aS VU.! z
                                                            in  if (  (  thirdC
                                                                      /= thirdK
                                                                      )
                                                                   || ( 2
                                                                      * secondI
                                                                      )
                                                                   == ( firstI
                                                                      + thirdI
                                                                      )
                                                                   )
                                                                then

                                                                    acc3
                                                                else
                                                                    acc3 + 1
                                                        )
                                                        0
                                                        [y + 1 .. VU.length aS
                                                            - 1]
                                                    )
                              )
                              0
                              [x + 1 .. lastLastI]
                          )
            )
            0
            [0 .. lastLastLastI]

    print ret

searchLastLast s x lastC =
    if s VU.! x == lastC then searchLastLast s (x - 1) lastC else x
searchLastLastLast s x lastC lastLastC =
    if s VU.! x == lastC || s VU.! x == lastLastC
        then searchLastLastLast s (x - 1) lastC lastLastC
        else x

seleK first second =
    let firstI = if first == 'R'
            then 1
            else if first == 'G' then 2 else if first == 'B' then 3 else 0
        secondI = if second == 'R'
            then 1
            else if second == 'G' then 2 else if second == 'B' then 3 else 0
        thirdI = firstI + secondI
    in  if thirdI == 3
            then 'B'
            else if thirdI == 4 then 'G' else if thirdI == 5 then 'R' else ' '