summaryrefslogblamecommitdiffstats
path: root/GC.rs
blob: 62dd7063ada31be775c6e5a0f34994cc8a3b0dde (plain) (tree)





































































                                                         
use io::{println,stdin,Reader,ReaderUtil};
use str::{push_str,unshift_char,each_char,len};

const EOF: char = -1 as char;

struct FASTAReader {
    in:              Reader,
    priv mut peeked: char,
}

impl FASTAReader {
    static fn new() -> FASTAReader {
        FASTAReader { in: stdin(), peeked: EOF }
    }

    fn read_line(&self) -> ~str {
        let mut line = self.in.read_line();
        if self.peeked != '>' {
            unshift_char(&mut line, self.peeked);
        }
        self.peeked = self.in.read_char();
        line
    }

    fn read_sequence(&self) -> (~str, ~str) {
        if self.peeked == EOF {
            self.peeked = self.in.read_char();
        }

        let name = self.read_line();
        let mut dna = ~"";
        while !self.in.eof() && self.peeked != '>' {
            let line = self.read_line();
            push_str(&mut dna, line);
        }
        (name, dna)
    }

    fn each_sequence(&self, cb: fn(~str, ~str) -> bool) {
        while !self.in.eof() {
            let (name, dna) = self.read_sequence();
            cb(name, dna);
        }
    }
}

pure fn gc_content(dna: ~str) -> float {
    let mut content = 0;
    for each_char(dna) |ch| {
        match ch {
            'C' | 'G' => content += 1,
            _         => (),
        }
    }
    (content as float) / (len(dna) as float)
}

fn main() {
    let reader = FASTAReader::new();
    let mut (max_name, max_gc) = (~"", -1f);
    for reader.each_sequence |name, dna| {
        let gc_content = gc_content(dna);
        if gc_content > max_gc {
            max_gc = gc_content;
            max_name = name;
        }
    }
    println(max_name);
    println(fmt!("%.6f", max_gc * 100f));
}