rosalind / src / rosalind / p004.clj

(ns rosalind.p004
  (:refer-clojure :exclude [char])
  (:require [the.parsatron :refer [defparser many1 always run string digit char
                                   eof let->> token between]]))

(defparser number []
  (let->> [ds (many1 (digit))]
    (always (apply str ds))))

(defparser dna-line []
  (let->> [nts (many1 (token #{\G \T \C \A}))
           _ (char \newline)]
    (always (apply str nts))))

(defparser dna []
  (let->> [ntls (many1 (dna-line))]
    (always (apply str ntls))))

(defparser header []
  (between (string ">Rosalind_") (char \newline)
           (number)))

(defparser chunk []
  (let->> [id (header)
           content (dna)]
    (always [id content])))

(defparser file []
  (let->> [chunks (many1 (chunk))
           _ (eof)
           ]
    (always chunks)))

(defn parse [s]
  (run (file) s))

(def sample
">Rosalind_6404
CCTGCGGAAGATCGGCACTAGAATAGCCAGAACCGTTTCTCTGAGGCTTCCGGCCTTCCC
TCCCACTAATAATTCTGAGG
>Rosalind_5959
CCATCGGTAGCGCATCCTTAGTCCAATTAAGTCCCTATCCAGGCGCTCCGCCGAAGGTCT
ATATCCATTTGTCAGCAGACACGC
>Rosalind_0808
CCACCCTCGTGGTATGGCTAGGCATTCAGGAACCGGAGAACGCTTCAGACCAGCCCGGAC
TGGGAACCTGCGGGCAGTAGGTGGAAT
"
)

(defn gc-content [dna]
  (float (/ (count (filter #{\G \C} dna))
            (count dna))))

(defn solve [s]
  (let [[id gcc] (last (sort-by second
                                 (map (juxt first (comp gc-content second))
                                      (parse s))))]
    (println (str "Rosalind_" id))
    (println (str (* 100 gcc) "%"))))

(solve sample)

(solve (slurp "/Users/sjl/Downloads/rosalind_gc.txt"))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.