forked from fsprojects/fantomas
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathknucleotide.fs
64 lines (56 loc) · 1.81 KB
/
knucleotide.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/// knucleotide.fs
///
/// The Computer Language Benchmarks Game
/// http://shootout.alioth.debian.org/
///
/// contributed by Jimmy Tang
module Knucleotide
open System
open System.IO
open System.Collections.Generic
/// make our hashtable using System.Collections.Generic.Dictionary
let maketable (dna : string) (length : int) =
let d = new Dictionary<_, _>()
for start in 0..(dna.Length - length) do
let substr = dna.Substring(start, length)
let x = ref (ref 0)
if d.TryGetValue(substr, x) then x.Value := ! !x + 1
else d.[substr] <- ref 1
d
/// frequency for all substrings of a given length
let frequencies (dna : string) (length : int) =
[ let d = maketable dna length
let total =
d.Values
|> Seq.map (!)
|> Seq.sum
yield! [ for pair in d ->
pair.Key.ToUpper(),
(float (pair.Value.Value) * 100.0 / float (total)) ]
|> List.sortBy (snd >> (~-))
|> List.map (fun (s, c) -> sprintf "%s %.3f" s c)
yield "" ]
// frequency of occurrence for a particular substring
let countSubstring dna (substring : string) =
[ let d = maketable dna (substring.Length)
yield (sprintf "%d\t%s" (if d.ContainsKey(substring) then !d.[substring]
else 0) (substring.ToUpper())) ]
let input = Console.In
let dna =
seq {
while true do
yield input.ReadLine()
}
|> Seq.takeWhile (fun x -> x <> null)
|> Seq.skipWhile (fun x -> not (x.StartsWith(">THREE")))
|> Seq.skip 1
|> String.concat ""
[ for len in [ 1; 2 ] -> async { return frequencies dna len } ]
@ [ for str in [ "ggt"; "ggta"; "ggtatt"; "ggtattttaatt"; "ggtattttaatttatagt" ] ->
async { return countSubstring dna str } ]
|> List.rev
|> Async.Parallel
|> Async.RunSynchronously
|> Array.rev
|> Seq.concat
|> Seq.iter (printfn "%s")