// matching (), [] and {} brackets. open System; let argv = Environment.GetCommandLineArgs(); let input = if argv.Length>2 then argv[2] else ""; let errpositions = Array.zeroCreate input.Length; let mutable errors = 0; let rec matchem stack positions index = if index >= input.Length then check_stack stack positions else match (stack,positions,input[index]) with | (s, p, '(') -> matchem ('('::s) (index::p) (index+1) | (s, p, '[') -> matchem ('['::s) (index::p) (index+1) | (s, p, '{') -> matchem ('{'::s) (index::p) (index+1) | ('('::s, i::p, ')') | ('['::s, i::p, ']') | ('{'::s, i::p, '}') -> matchem s p (index+1) | (a::s, i::p, (')' as c)) | (a::s, i::p, (']' as c)) | (a::s, i::p, ('}' as c)) -> errors <- errors + 1 eprintfn "%d. mismatched %c and %c at indices %d and %d" errors a c i index errpositions[i] <- errors errpositions[index] <- errors matchem s p (index+1) | ([], [], (')' as c)) | ([],[],(']' as c)) | ([],[],('}' as c)) -> errors <- errors + 1 eprintfn "%d. unmatched %c at index %d" errors c index errpositions[index] <- errors matchem [] [] (index+1) | (s, p, x) -> matchem s p (index+1) and check_stack stack positions = match (stack,positions) with | ([],p) -> if errors=0 then printfn "All brackets match" else printfn "There were %d errors" errors | ('(' as c::s, i::p) | ('[' as c::s, i::p) | ('{' as c::s, i::p) -> errors <- errors + 1 eprintfn "%d. unmatched %c at index %d" errors c i errpositions[i] <- errors check_stack s p | (a::b, p) -> check_stack b p matchem [] [] 0 if errors>0 then printfn "%s" input for i in 0..input.Length-1 do if errpositions[i]>0 && errpositions[i]<10 then printf "^" else printf " " printfn "" for i in 0..input.Length-1 do if errpositions[i]>0 && errpositions[i]<10 then printf "%d" errpositions[i] else printf " " printfn ""