1
2
3
4
32
33
38
39 package main
40
41 import (
42 "fmt"
43 "io"
44 "os"
45 "regexp"
46 "runtime"
47 )
48
49 var variants = []string{
50 "agggtaaa|tttaccct",
51 "[cgt]gggtaaa|tttaccc[acg]",
52 "a[act]ggtaaa|tttacc[agt]t",
53 "ag[act]gtaaa|tttac[agt]ct",
54 "agg[act]taaa|ttta[agt]cct",
55 "aggg[acg]aaa|ttt[cgt]ccct",
56 "agggt[cgt]aa|tt[acg]accct",
57 "agggta[cgt]a|t[acg]taccct",
58 "agggtaa[cgt]|[acg]ttaccct",
59 }
60
61 type Subst struct {
62 pat, repl string
63 }
64
65 var substs = []Subst{
66 Subst{"B", "(c|g|t)"},
67 Subst{"D", "(a|g|t)"},
68 Subst{"H", "(a|c|t)"},
69 Subst{"K", "(g|t)"},
70 Subst{"M", "(a|c)"},
71 Subst{"N", "(a|c|g|t)"},
72 Subst{"R", "(a|g)"},
73 Subst{"S", "(c|g)"},
74 Subst{"V", "(a|c|g)"},
75 Subst{"W", "(a|t)"},
76 Subst{"Y", "(c|t)"},
77 }
78
79 func countMatches(pat string, bytes []byte) int {
80 re := regexp.MustCompile(pat)
81 n := 0
82 for {
83 e := re.FindIndex(bytes)
84 if e == nil {
85 break
86 }
87 n++
88 bytes = bytes[e[1]:]
89 }
90 return n
91 }
92
93 func main() {
94 runtime.GOMAXPROCS(4)
95 bytes, err := io.ReadAll(os.Stdin)
96 if err != nil {
97 fmt.Fprintf(os.Stderr, "can't read input: %s\n", err)
98 os.Exit(2)
99 }
100 ilen := len(bytes)
101
102 bytes = regexp.MustCompile("(>[^\n]+)?\n").ReplaceAll(bytes, []byte{})
103 clen := len(bytes)
104
105 mresults := make([]chan int, len(variants))
106 for i, s := range variants {
107 ch := make(chan int)
108 mresults[i] = ch
109 go func(ss string) {
110 ch <- countMatches(ss, bytes)
111 }(s)
112 }
113
114 lenresult := make(chan int)
115 bb := bytes
116 go func() {
117 for _, sub := range substs {
118 bb = regexp.MustCompile(sub.pat).ReplaceAll(bb, []byte(sub.repl))
119 }
120 lenresult <- len(bb)
121 }()
122
123 for i, s := range variants {
124 fmt.Printf("%s %d\n", s, <-mresults[i])
125 }
126 fmt.Printf("\n%d\n%d\n%d\n", ilen, clen, <-lenresult)
127 }
128
View as plain text