[Shootout-list] OCaml reverse-complement

Christophe TROESTLER del-con@tiscali.be
Sun, 27 Mar 2005 03:18:23 +0200 (CEST)


----Next_Part(Sun_Mar_27_03_18_23_2005_881)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi,

Here is an implementation of the reverse-complement benchmark in
OCaml.

Cheers,
ChriS

----Next_Part(Sun_Mar_27_03_18_23_2005_881)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="reverse-complement.ml"

(* reverse-complement.ml
 *
 * The Great Computer Language Shootout
 * http://shootout.alioth.debian.org/
 *
 * Contributed by Troestler Christophe
 *)


let complement =
  let cplt = Array.init 256 (fun i -> Char.chr i) in
  List.iter (fun (c1, c2) ->
	       cplt.(Char.code c1) <- c2;
	       cplt.(Char.code c2) <- c1;
	       cplt.(Char.code(Char.lowercase c1)) <- c2;
	       cplt.(Char.code(Char.lowercase c2)) <- c1;  )
    [ ('A','T'); ('C','G'); ('B','V'); ('D','H'); ('K','M'); ('R','Y') ];
  cplt

(* [reverse s] reverse-complement the string [s] in place. *)
let reverse s =
  let rec rev i j =
    if i < j then (
      let si = s.[i] in
      s.[i] <- complement.(Char.code s.[j]);
      s.[j] <- complement.(Char.code si);
      rev (i + 1) (j - 1)
    ) in
  rev 0 (String.length s - 1);
  s

let print_fasta =
  let rec print60 pos len dna =
    if len > 60 then (
      output stdout dna pos 60; print_string "\n";
      print60 (pos + 60) (len - 60) dna
    )
    else (output stdout dna pos len; print_string "\n") in
  fun dna -> print60 0 (String.length dna) dna


let () =
  let buf = Buffer.create 4096 in
  try while true do
    let line = input_line stdin in
    if String.length line > 0 && line.[0] = '>' then (
      if Buffer.length buf > 0 then print_fasta(reverse(Buffer.contents buf));
      Buffer.clear buf;
      print_endline line
    )
    else Buffer.add_string buf line
  done with End_of_file -> print_fasta(reverse(Buffer.contents buf))


----Next_Part(Sun_Mar_27_03_18_23_2005_881)----