Browse Source
* add rosalind package that will be go get friendly * update readme with new structure and approach * moving data to rosalind dir * add travis.yml filemaster
19 changed files with 2381 additions and 26 deletions
@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
|
||||
language: go |
||||
go_import_path: github.com/charlesreid1/go-rosalind/rosalind |
||||
go: |
||||
- 1.10.x |
||||
- 1.11.x |
||||
- tip |
||||
|
||||
script: |
||||
- go test -v ./rosalind/... |
@ -1,41 +1,49 @@
@@ -1,41 +1,49 @@
|
||||
# Go-Rosalind |
||||
# go-rosalind |
||||
|
||||
Solving problems from Rosalind.info using Go |
||||
_A Go (golang) package for solving bioinformatics problems._ |
||||
|
||||
## Organization |
||||
|
||||
Each chapter has its own directory. |
||||
## Summary |
||||
|
||||
Within the chapter directory, each problem has |
||||
its own driver program, which prints info about |
||||
the problem, loads the input file from Rosalind, |
||||
and prints the solution. Each problem also has |
||||
its own test suite using the examples provided |
||||
on Rosalind.info. |
||||
|
||||
For example, the function that loads the |
||||
input file for problem BA1A is in `ba1a.go` |
||||
and the code to test the functionality |
||||
of the solution to BA1A is in `ba1a_test.go`. |
||||
This repository contains a Go (golang) library called `rosalind` |
||||
that provides a set of functions that are useful for solving |
||||
bioinformatics problems from Rosalind.info. |
||||
|
||||
## Quick Start |
||||
|
||||
To run all the tests in a chapter directory: |
||||
This library can be installed using `go get`: |
||||
|
||||
``` |
||||
go test -v |
||||
go get https://github.com/charlesreid1/go-rosalind/rosalind |
||||
``` |
||||
|
||||
To run only a particular problem: |
||||
The library can now be imported and its functions called directly. |
||||
Here is a brief example: |
||||
|
||||
1. Edit `main.go` to call the right method |
||||
for the right problem with the right input |
||||
file name. |
||||
``` |
||||
package main |
||||
|
||||
2. Run `main.go` using `go run`, and point Go |
||||
to all the relevant Go files: |
||||
import "roslind" |
||||
|
||||
func main() { |
||||
input := "AAAATGCGCTAGTAAAAGTCACTGAAAA" |
||||
k := 4 |
||||
result, err := rosalind.MostFrequentKmers(input, k) |
||||
} |
||||
``` |
||||
go run main.go utils.go rosalind.go <name-of-BA-file> |
||||
``` |
||||
|
||||
## Command Line Interface |
||||
|
||||
TBA |
||||
|
||||
## Organization |
||||
|
||||
The repo contains the following directories: |
||||
|
||||
* `chapter01/` - initial working directory; standalone code |
||||
|
||||
* `chapter02/` - first set of solutions utilizing `rosalind` library |
||||
|
||||
* `rosalind/` - contains Rosalind library |
||||
|
||||
See the Readme file in each respective directory for more info. |
||||
|
||||
|
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
# rosalind go package |
||||
|
||||
This directory contains the `rosalind` Go package. |
||||
|
@ -0,0 +1,124 @@
@@ -0,0 +1,124 @@
|
||||
package rosalind |
||||
|
||||
import ( |
||||
"bufio" |
||||
"fmt" |
||||
"os" |
||||
) |
||||
|
||||
// readLines reads a whole file into memory
|
||||
// and returns a slice of its lines.
|
||||
func readLines(path string) ([]string, error) { |
||||
file, err := os.Open(path) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
defer file.Close() |
||||
|
||||
var lines []string |
||||
scanner := bufio.NewScanner(file) |
||||
buf := make([]byte, 2) |
||||
|
||||
// This is awkward.
|
||||
// Scanners aren't good for big files,
|
||||
// just simple stuff.
|
||||
BIGNUMBER := 90000 |
||||
scanner.Buffer(buf, BIGNUMBER) |
||||
for scanner.Scan() { |
||||
lines = append(lines, scanner.Text()) |
||||
} |
||||
return lines, scanner.Err() |
||||
} |
||||
|
||||
// writeLines writes the lines to the given file.
|
||||
func writeLines(lines []string, path string) error { |
||||
file, err := os.Create(path) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
defer file.Close() |
||||
|
||||
w := bufio.NewWriter(file) |
||||
for _, line := range lines { |
||||
fmt.Fprintln(w, line) |
||||
} |
||||
return w.Flush() |
||||
} |
||||
|
||||
// Utility function: check if two string arrays/array slices
|
||||
// are equal. This is necessary because of squirrely
|
||||
// behavior when comparing arrays (of type [1]string)
|
||||
// and slices (of type []string).
|
||||
func EqualStringSlices(a, b []string) bool { |
||||
if len(a) != len(b) { |
||||
return false |
||||
} |
||||
for i := 0; i < len(a); i++ { |
||||
if a[i] != b[i] { |
||||
return false |
||||
} |
||||
} |
||||
return true |
||||
} |
||||
|
||||
// Utility function: check if two boolean arrays/array slices
|
||||
// are equal. This is necessary because of squirrely
|
||||
// behavior when comparing arrays (of type [1]bool)
|
||||
// and slices (of type []bool).
|
||||
func EqualBoolSlices(a, b []bool) bool { |
||||
if len(a) != len(b) { |
||||
return false |
||||
} |
||||
for i := 0; i < len(a); i++ { |
||||
if a[i] != b[i] { |
||||
return false |
||||
} |
||||
} |
||||
return true |
||||
} |
||||
|
||||
// Check if two int arrays/array slices are equal.
|
||||
func EqualIntSlices(a, b []int) bool { |
||||
if len(a) != len(b) { |
||||
return false |
||||
} |
||||
for i := 0; i < len(a); i++ { |
||||
if a[i] != b[i] { |
||||
return false |
||||
} |
||||
} |
||||
return true |
||||
} |
||||
|
||||
// Compute the factorial of an integer.
|
||||
func Factorial(n int) int { |
||||
if n < 2 { |
||||
// base case
|
||||
return 1 |
||||
} else { |
||||
// recursive case
|
||||
return n * Factorial(n-1) |
||||
} |
||||
} |
||||
|
||||
// Returns value of Binomial Coefficient Binom(n, k).
|
||||
func Binomial(n, k int) int { |
||||
|
||||
result := 1 |
||||
|
||||
// Since C(n, k) = C(n, n-k)
|
||||
if k > (n - k) { |
||||
k = n - k |
||||
} |
||||
|
||||
// Calculate value of:
|
||||
// ( n * (n-1) * ... * (n-k+1) )
|
||||
// -----------------------------
|
||||
// ( k * (k-1) * ... * 1 )
|
||||
for i := 0; i < k; i++ { |
||||
result *= n - i |
||||
result /= i + 1 |
||||
} |
||||
|
||||
return result |
||||
} |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
package rosalind |
||||
|
||||
import "testing" |
||||
|
||||
func TestEqualStringSlices(t *testing.T) { |
||||
a := []string{"peanut", "butter", "jelly", "time"} |
||||
b := make([]string, 4) |
||||
b[0] = "peanut" |
||||
b[1] = "butter" |
||||
b[2] = "jelly" |
||||
b[3] = "time" |
||||
if !EqualStringSlices(a, b) { |
||||
msg := "Error: EqualStringSlices() is broken!" |
||||
t.Fatal(msg) |
||||
} |
||||
} |
||||
|
||||
func TestEqualBoolSlices(t *testing.T) { |
||||
a := []bool{true, true, true, false, false, false, true, true, true} |
||||
b := make([]bool, 9) |
||||
b[0], b[1], b[2] = true, true, true |
||||
b[3], b[4], b[5] = false, false, false |
||||
b[6], b[7], b[8] = true, true, true |
||||
if !EqualBoolSlices(a, b) { |
||||
msg := "Error: EqualBoolSlices() is broken!" |
||||
t.Fatal(msg) |
||||
} |
||||
} |
||||
|
||||
func TestEqualIntSlices(t *testing.T) { |
||||
a := []int{3, 1, 4, 1, 5, 9} |
||||
b := make([]int, 6) |
||||
b[0], b[1], b[2] = 3, 1, 4 |
||||
b[3], b[4], b[5] = 1, 5, 9 |
||||
if !EqualIntSlices(a, b) { |
||||
msg := "Error: EqualIntSlices() is broken!" |
||||
t.Fatal(msg) |
||||
} |
||||
} |
Loading…
Reference in new issue