...
1
2
3
4
32
33
38
39 package main
40
41 import (
42 "bufio"
43 "bytes"
44 "fmt"
45 "io"
46 "os"
47 "runtime"
48 "sort"
49 )
50
51 func count(data string, n int) map[string]int {
52 counts := make(map[string]int)
53 top := len(data) - n
54 for i := 0; i <= top; i++ {
55 s := data[i : i+n]
56 counts[s]++
57 }
58 return counts
59 }
60
61 func countOne(data string, s string) int {
62 return count(data, len(s))[s]
63 }
64
65 type kNuc struct {
66 name string
67 count int
68 }
69
70 type kNucArray []kNuc
71
72 func (kn kNucArray) Len() int { return len(kn) }
73 func (kn kNucArray) Swap(i, j int) { kn[i], kn[j] = kn[j], kn[i] }
74 func (kn kNucArray) Less(i, j int) bool {
75 if kn[i].count == kn[j].count {
76 return kn[i].name > kn[j].name
77 }
78 return kn[i].count > kn[j].count
79 }
80
81 func sortedArray(m map[string]int) kNucArray {
82 kn := make(kNucArray, len(m))
83 i := 0
84 for k, v := range m {
85 kn[i] = kNuc{k, v}
86 i++
87 }
88 sort.Sort(kn)
89 return kn
90 }
91
92 func printKnucs(a kNucArray) {
93 sum := 0
94 for _, kn := range a {
95 sum += kn.count
96 }
97 for _, kn := range a {
98 fmt.Printf("%s %.3f\n", kn.name, 100*float64(kn.count)/float64(sum))
99 }
100 fmt.Print("\n")
101 }
102
103 func main() {
104 runtime.GOMAXPROCS(4)
105 in := bufio.NewReader(os.Stdin)
106 three := []byte(">THREE ")
107 for {
108 line, err := in.ReadSlice('\n')
109 if err != nil {
110 fmt.Fprintln(os.Stderr, "ReadLine err:", err)
111 os.Exit(2)
112 }
113 if line[0] == '>' && bytes.Equal(line[0:len(three)], three) {
114 break
115 }
116 }
117 data, err := io.ReadAll(in)
118 if err != nil {
119 fmt.Fprintln(os.Stderr, "ReadAll err:", err)
120 os.Exit(2)
121 }
122
123 j := 0
124 for i := 0; i < len(data); i++ {
125 if data[i] != '\n' {
126 data[j] = data[i] &^ ' '
127 j++
128 }
129 }
130 str := string(data[0:j])
131
132 var arr1, arr2 kNucArray
133 countsdone := make(chan bool)
134 go func() {
135 arr1 = sortedArray(count(str, 1))
136 countsdone <- true
137 }()
138 go func() {
139 arr2 = sortedArray(count(str, 2))
140 countsdone <- true
141 }()
142
143 interests := []string{"GGT", "GGTA", "GGTATT", "GGTATTTTAATT", "GGTATTTTAATTTATAGT"}
144 results := make([]chan string, len(interests))
145 for i, s := range interests {
146 ch := make(chan string)
147 results[i] = ch
148 go func(result chan string, ss string) {
149 result <- fmt.Sprintf("%d %s\n", countOne(str, ss), ss)
150 }(ch, s)
151 }
152 <-countsdone
153 <-countsdone
154 printKnucs(arr1)
155 printKnucs(arr2)
156 for _, rc := range results {
157 fmt.Print(<-rc)
158 }
159
160 }
161
View as plain text