Yep, stack-based trick worked just fine:
let reactQuickly input =
Seq.fold (fun s c ->
let last = if Array.length s > 0 then Some (Array.last s) else None
match last with
| Some x ->
if c <> x && (x = System.Char.ToUpper c || x = System.Char.ToLower c) then
Array.sub s 0 (Array.length s - 1)
else Array.append s [| c |]
| None -> Array.append s [| c |]) [| |] input
Replacing reactString with reactQuickly was enough to bring the total runtime from several (many) minutes to around 3 seconds.
Using the tip from @choroba
and reducing everything first would probably speed it up even more.
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.