Updating the Repo
This commit is contained in:
parent
ec45e6b2eb
commit
739f3c3e2b
@ -1 +1 @@
|
||||
hello-world
|
||||
packages.config
|
@ -1 +1 @@
|
||||
bob
|
||||
Debug
|
1
csharp/current
Symbolic link
1
csharp/current
Symbolic link
@ -0,0 +1 @@
|
||||
bob
|
12
dlang/hello-world/hello_world.d
Normal file
12
dlang/hello-world/hello_world.d
Normal file
@ -0,0 +1,12 @@
|
||||
module helloworld_test;
|
||||
|
||||
import std.stdio;
|
||||
|
||||
void main() {
|
||||
assert(hello() == "Hello, World!");
|
||||
assert(hello("Alice") == "Hello, Alice!");
|
||||
assert(hello("Bob") == "Hello, Bob!");
|
||||
assert(hello("") == "Hello, !");
|
||||
|
||||
writeln("All tests passed.");
|
||||
}
|
@ -1 +1 @@
|
||||
hello-world
|
||||
example
|
1
go/current
Symbolic link
1
go/current
Symbolic link
@ -0,0 +1 @@
|
||||
matrix
|
53
go/grade-school/README.md
Normal file
53
go/grade-school/README.md
Normal file
@ -0,0 +1,53 @@
|
||||
# Grade School
|
||||
|
||||
Write a small archiving program that stores students' names along with the grade that they are in.
|
||||
|
||||
In the end, you should be able to:
|
||||
|
||||
- Add a student's name to the roster for a grade
|
||||
- "Add Jim to grade 2."
|
||||
- "OK."
|
||||
- Get a list of all students enrolled in a grade
|
||||
- "Which students are in grade 2?"
|
||||
- "We've only got Jim just now."
|
||||
- Get a sorted list of all students in all grades. Grades should sort
|
||||
as 1, 2, 3, etc., and students within a grade should be sorted
|
||||
alphabetically by name.
|
||||
- "Who all is enrolled in school right now?"
|
||||
- "Grade 1: Anna, Barb, and Charlie. Grade 2: Alex, Peter, and Zoe.
|
||||
Grade 3…"
|
||||
|
||||
Note that all our students only have one name. (It's a small town, what
|
||||
do you want?)
|
||||
|
||||
|
||||
## For bonus points
|
||||
|
||||
Did you get the tests passing and the code clean? If you want to, these
|
||||
are some additional things you could try:
|
||||
|
||||
- If you're working in a language with mutable data structures and your
|
||||
implementation allows outside code to mutate the school's internal DB
|
||||
directly, see if you can prevent this. Feel free to introduce additional
|
||||
tests.
|
||||
|
||||
Then please share your thoughts in a comment on the submission. Did this
|
||||
experiment make the code better? Worse? Did you learn anything from it?
|
||||
|
||||
To run the tests simply run the command `go test` in the exercise directory.
|
||||
|
||||
If the test suite contains benchmarks, you can run these with the `-bench`
|
||||
flag:
|
||||
|
||||
go test -bench .
|
||||
|
||||
For more detailed info about the Go track see the [help
|
||||
page](http://exercism.io/languages/go).
|
||||
|
||||
## Source
|
||||
|
||||
A pairing session with Phil Battos at gSchool [http://gschool.it](http://gschool.it)
|
||||
|
||||
## Submitting Incomplete Problems
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
||||
|
173
go/grade-school/grade_school_test.go
Normal file
173
go/grade-school/grade_school_test.go
Normal file
@ -0,0 +1,173 @@
|
||||
// API:
|
||||
//
|
||||
// type Grade struct {
|
||||
// int, []string
|
||||
// }
|
||||
//
|
||||
// type School
|
||||
// func New() *School
|
||||
// func (s *School) Add(string, int)
|
||||
// func (s *School) Grade(int) []string
|
||||
// func (s *School) Enrollment() []Grade
|
||||
|
||||
package school
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewSchoolIsEmpty(t *testing.T) {
|
||||
if len(New().Enrollment()) != 0 {
|
||||
t.Error("New school not empty")
|
||||
}
|
||||
}
|
||||
|
||||
func list(e []Grade) (s string) {
|
||||
for _, l := range e {
|
||||
s += fmt.Sprintln(l)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func TestAddStudent(t *testing.T) {
|
||||
exp := list([]Grade{{2, []string{"Aimee"}}})
|
||||
s := New()
|
||||
s.Add("Aimee", 2)
|
||||
got := list(s.Enrollment())
|
||||
if got != exp {
|
||||
t.Errorf(`Add Aimee level 2, got
|
||||
%sexpected:
|
||||
%s`, got, exp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddMoreSameGrade(t *testing.T) {
|
||||
exp := list([]Grade{{2, []string{"Blair James Paul"}}})
|
||||
s := New()
|
||||
s.Add("Blair", 2)
|
||||
s.Add("James", 2)
|
||||
s.Add("Paul", 2)
|
||||
got := list(s.Enrollment())
|
||||
if got != exp {
|
||||
t.Errorf(`Add more same grade, got
|
||||
%sexpected:
|
||||
%s`, got, exp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddDifferentGrades(t *testing.T) {
|
||||
exp := list([]Grade{
|
||||
{3, []string{"Chelsea"}},
|
||||
{7, []string{"Logan"}},
|
||||
})
|
||||
s := New()
|
||||
s.Add("Chelsea", 3)
|
||||
s.Add("Logan", 7)
|
||||
got := list(s.Enrollment())
|
||||
if got != exp {
|
||||
t.Errorf(`Add different grades, got
|
||||
%sexpected:
|
||||
%s`, got, exp)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetGrade(t *testing.T) {
|
||||
exp := []string{"Bradley", "Franklin"}
|
||||
s := New()
|
||||
s.Add("Bradley", 5)
|
||||
s.Add("Franklin", 5)
|
||||
s.Add("Jeff", 1)
|
||||
got := s.Grade(5)
|
||||
if len(got) == len(exp) {
|
||||
if got[0] == exp[0] && got[1] == exp[1] ||
|
||||
got[0] == exp[1] && got[1] == exp[0] { // accept out of order
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Errorf(`Get grade, got
|
||||
%v
|
||||
expected
|
||||
%v`, got, exp)
|
||||
}
|
||||
|
||||
func TestNonExistantGrade(t *testing.T) {
|
||||
s := New()
|
||||
got := s.Grade(1)
|
||||
if len(got) != 0 {
|
||||
t.Errorf(`Get non-existant grade, got
|
||||
%v
|
||||
expected
|
||||
[]`, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortedEnrollment(t *testing.T) {
|
||||
exp := list([]Grade{
|
||||
{3, []string{"Kyle"}},
|
||||
{4, []string{"Christopher Jennifer"}},
|
||||
{6, []string{"Kareem"}},
|
||||
})
|
||||
s := New()
|
||||
s.Add("Jennifer", 4)
|
||||
s.Add("Kareem", 6)
|
||||
s.Add("Christopher", 4)
|
||||
s.Add("Kyle", 3)
|
||||
got := list(s.Enrollment())
|
||||
if got != exp {
|
||||
t.Errorf(`Sorted enrollment, got
|
||||
%sexpected:
|
||||
%s`, got, exp)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
minLevel = 1
|
||||
maxLevel = 9
|
||||
enrollment = 400
|
||||
)
|
||||
|
||||
func BenchmarkAddStudents(b *testing.B) {
|
||||
const pool = 1e6 // pool of students
|
||||
names := make([]string, pool)
|
||||
levels := make([]int, pool)
|
||||
for i := range names {
|
||||
names[i] = strconv.Itoa(rand.Intn(1e5))
|
||||
levels[i] = minLevel + rand.Intn(maxLevel-minLevel+1)
|
||||
}
|
||||
p := 0
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
// bench combined time to create a school and add
|
||||
// a number of students, drawn from a pool of students
|
||||
s := New()
|
||||
for t := 0; t < enrollment; t++ {
|
||||
s.Add(names[p], levels[p])
|
||||
p = (p + 1) % pool
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEnrollment(b *testing.B) {
|
||||
const pool = 1000 // pool of schools
|
||||
ss := make([]*School, pool)
|
||||
for i := range ss {
|
||||
s := New()
|
||||
for t := 0; t < enrollment; t++ {
|
||||
s.Add(
|
||||
strconv.Itoa(rand.Intn(1e5)),
|
||||
minLevel+rand.Intn(maxLevel-minLevel+1))
|
||||
}
|
||||
ss[i] = s
|
||||
}
|
||||
p := 0
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
// bench time to get enrollment of a full school,
|
||||
// averaged over a pool of schools.
|
||||
ss[p].Enrollment()
|
||||
p = (p + 1) % pool
|
||||
}
|
||||
}
|
53
go/grade-school/school.go
Normal file
53
go/grade-school/school.go
Normal file
@ -0,0 +1,53 @@
|
||||
package school
|
||||
|
||||
import "sort"
|
||||
|
||||
// A Grade is just the grade number and a list of students
|
||||
type Grade struct {
|
||||
Num int
|
||||
Students []string
|
||||
}
|
||||
|
||||
// AddStudent adds a student name to a grades roster
|
||||
func (g *Grade) AddStudent(name string) {
|
||||
g.Students = append(g.Students, name)
|
||||
}
|
||||
|
||||
// School is just a collection of Grades
|
||||
type School struct {
|
||||
grades map[int]Grade
|
||||
}
|
||||
|
||||
// New returns a new School object
|
||||
func New() *School {
|
||||
return &School{
|
||||
grades: make(map[int]Grade),
|
||||
}
|
||||
}
|
||||
|
||||
// Add add student 'name' to grade 'grade'
|
||||
func (s *School) Add(name string, grade int) {
|
||||
g := s.grades[grade]
|
||||
g.Num = grade
|
||||
g.AddStudent(name)
|
||||
s.grades[grade] = g
|
||||
}
|
||||
|
||||
// Grade returns a sorted list of all students in 'grade'
|
||||
func (s *School) Grade(grade int) []string {
|
||||
g := s.grades[grade]
|
||||
sort.Strings(g.Students)
|
||||
return g.Students
|
||||
}
|
||||
|
||||
// Enrollment returns the full school's enrollment, sorted by grade then name
|
||||
func (s *School) Enrollment() []Grade {
|
||||
var ret []Grade
|
||||
for k := 1; k <= 12; k++ {
|
||||
grRoster := s.Grade(k)
|
||||
if len(grRoster) > 0 {
|
||||
ret = append(ret, Grade{Num: k, Students: grRoster})
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
56
go/matrix/README.md
Normal file
56
go/matrix/README.md
Normal file
@ -0,0 +1,56 @@
|
||||
# Matrix
|
||||
|
||||
Write a program that, given a string representing a matrix of numbers, can return the rows and columns of that matrix.
|
||||
|
||||
So given a string with embedded newlines like:
|
||||
|
||||
> 9 8 7
|
||||
> 5 3 2
|
||||
> 6 6 7
|
||||
|
||||
representing this matrix:
|
||||
|
||||
```plain
|
||||
0 1 2
|
||||
|---------
|
||||
0 | 9 8 7
|
||||
1 | 5 3 2
|
||||
2 | 6 6 7
|
||||
```
|
||||
|
||||
your code should be able to spit out:
|
||||
|
||||
- A list of the rows, reading each row left-to-right while moving
|
||||
top-to-bottom across the rows,
|
||||
- A list of the columns, reading each column top-to-bottom while moving
|
||||
from left-to-right.
|
||||
|
||||
The rows for our example matrix:
|
||||
|
||||
- 9, 8, 7
|
||||
- 5, 3, 2
|
||||
- 6, 6, 7
|
||||
|
||||
And its columns:
|
||||
|
||||
- 9, 5, 6
|
||||
- 8, 3, 6
|
||||
- 7, 2, 7
|
||||
|
||||
To run the tests simply run the command `go test` in the exercise directory.
|
||||
|
||||
If the test suite contains benchmarks, you can run these with the `-bench`
|
||||
flag:
|
||||
|
||||
go test -bench .
|
||||
|
||||
For more detailed info about the Go track see the [help
|
||||
page](http://exercism.io/languages/go).
|
||||
|
||||
## Source
|
||||
|
||||
Warmup to the `saddle-points` warmup. [http://jumpstartlab.com](http://jumpstartlab.com)
|
||||
|
||||
## Submitting Incomplete Problems
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
||||
|
265
go/matrix/matrix_test.go
Normal file
265
go/matrix/matrix_test.go
Normal file
@ -0,0 +1,265 @@
|
||||
// For the Matrix exercise in Go you have to do a few things not mentioned
|
||||
// in the README.
|
||||
//
|
||||
// 1. You must implement a constructor and methods Rows() and Cols() as
|
||||
// described in the README, but Rows() and Cols must return results that
|
||||
// are independent from the original matrix. That is, you should be able
|
||||
// to do as you please with the results without affecting the matrix.
|
||||
//
|
||||
// 2. You must implement a method Set(row, col, val) for setting a matrix
|
||||
// element.
|
||||
//
|
||||
// 3. As usual in Go, you must detect and return error conditions.
|
||||
|
||||
package matrix
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var tests = []struct {
|
||||
in string
|
||||
ok bool
|
||||
rows [][]int
|
||||
cols [][]int
|
||||
}{
|
||||
{"1 2\n10 20",
|
||||
true,
|
||||
[][]int{
|
||||
{1, 2},
|
||||
{10, 20},
|
||||
},
|
||||
[][]int{
|
||||
{1, 10},
|
||||
{2, 20},
|
||||
},
|
||||
},
|
||||
{"9 7\n8 6",
|
||||
true,
|
||||
[][]int{
|
||||
{9, 7},
|
||||
{8, 6},
|
||||
},
|
||||
[][]int{
|
||||
{9, 8},
|
||||
{7, 6},
|
||||
},
|
||||
},
|
||||
{"9 8 7\n19 18 17",
|
||||
true,
|
||||
[][]int{
|
||||
{9, 8, 7},
|
||||
{19, 18, 17},
|
||||
},
|
||||
[][]int{
|
||||
{9, 19},
|
||||
{8, 18},
|
||||
{7, 17},
|
||||
},
|
||||
},
|
||||
{"1 4 9\n16 25 36",
|
||||
true,
|
||||
[][]int{
|
||||
{1, 4, 9},
|
||||
{16, 25, 36},
|
||||
},
|
||||
[][]int{
|
||||
{1, 16},
|
||||
{4, 25},
|
||||
{9, 36},
|
||||
},
|
||||
},
|
||||
{"1 2 3\n4 5 6\n7 8 9\n 8 7 6",
|
||||
true,
|
||||
[][]int{
|
||||
{1, 2, 3},
|
||||
{4, 5, 6},
|
||||
{7, 8, 9},
|
||||
{8, 7, 6},
|
||||
},
|
||||
[][]int{
|
||||
{1, 4, 7, 8},
|
||||
{2, 5, 8, 7},
|
||||
{3, 6, 9, 6},
|
||||
},
|
||||
},
|
||||
{"89 1903 3\n18 3 1\n9 4 800",
|
||||
true,
|
||||
[][]int{
|
||||
{89, 1903, 3},
|
||||
{18, 3, 1},
|
||||
{9, 4, 800},
|
||||
},
|
||||
[][]int{
|
||||
{89, 18, 9},
|
||||
{1903, 3, 4},
|
||||
{3, 1, 800},
|
||||
},
|
||||
},
|
||||
{"1 2 3", // valid, 1 row, 3 columns
|
||||
true,
|
||||
[][]int{
|
||||
{1, 2, 3},
|
||||
},
|
||||
[][]int{
|
||||
{1},
|
||||
{2},
|
||||
{3},
|
||||
},
|
||||
},
|
||||
{"1\n2\n3", // valid, 3 rows, 1 column
|
||||
true,
|
||||
[][]int{
|
||||
{1},
|
||||
{2},
|
||||
{3},
|
||||
},
|
||||
[][]int{
|
||||
{1, 2, 3},
|
||||
},
|
||||
},
|
||||
{"0", // valid, 1 row, 1 column
|
||||
true,
|
||||
[][]int{
|
||||
{0},
|
||||
},
|
||||
[][]int{
|
||||
{0},
|
||||
},
|
||||
},
|
||||
{"9223372036854775808", false, nil, nil}, // overflows int64
|
||||
{"1 2\n10 20 30", false, nil, nil}, // uneven rows
|
||||
{"\n3 4\n5 6", false, nil, nil}, // first row empty
|
||||
{"1 2\n\n5 6", false, nil, nil}, // middle row empty
|
||||
{"1 2\n3 4\n", false, nil, nil}, // last row empty
|
||||
{"2.7", false, nil, nil}, // non-int
|
||||
{"cat", false, nil, nil}, // non-numeric
|
||||
// undefined
|
||||
// {"\n\n", // valid?, 3 rows, 0 columns
|
||||
// {"", // valid?, 0 rows, 0 columns
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
m, err := New(test.in)
|
||||
switch {
|
||||
case err != nil:
|
||||
if test.ok {
|
||||
t.Fatalf("New(%q) returned error %q. Error not expected",
|
||||
test.in, err)
|
||||
}
|
||||
case !test.ok:
|
||||
t.Fatalf("New(%q) = %v, %v. Expected non-nil error.",
|
||||
test.in, m, err)
|
||||
case m == nil:
|
||||
t.Fatalf("New(%q) = %v, want non-nil *Matrix",
|
||||
test.in, m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRows(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
if !test.ok {
|
||||
continue
|
||||
}
|
||||
m, err := New(test.in)
|
||||
if err != nil {
|
||||
t.Skip("Need working New for TestRows")
|
||||
}
|
||||
r := m.Rows()
|
||||
if len(r) == 0 && len(test.rows) == 0 {
|
||||
continue // agreement, and nothing more to test
|
||||
}
|
||||
if !reflect.DeepEqual(r, test.rows) {
|
||||
t.Fatalf("New(%q).Rows() = %v, want %v", test.in, r, test.rows)
|
||||
}
|
||||
if len(r[0]) == 0 {
|
||||
continue // not currently in test data, but anyway
|
||||
}
|
||||
r[0][0]++
|
||||
if !reflect.DeepEqual(m.Rows(), test.rows) {
|
||||
t.Fatalf("Matrix.Rows() returned slice based on Matrix " +
|
||||
"representation. Want independent copy of element data.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCols(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
if !test.ok {
|
||||
continue
|
||||
}
|
||||
m, err := New(test.in)
|
||||
if err != nil {
|
||||
t.Skip("Need working New for TestCols")
|
||||
}
|
||||
c := m.Cols()
|
||||
if len(c) == 0 && len(test.cols) == 0 {
|
||||
continue // agreement, and nothing more to test
|
||||
}
|
||||
if !reflect.DeepEqual(c, test.cols) {
|
||||
t.Fatalf("New(%q).Cols() = %v, want %v", test.in, c, test.cols)
|
||||
}
|
||||
if len(c[0]) == 0 {
|
||||
continue // not currently in test data, but anyway
|
||||
}
|
||||
c[0][0]++
|
||||
if !reflect.DeepEqual(m.Cols(), test.cols) {
|
||||
t.Fatalf("Matrix.Cols() returned slice based on Matrix " +
|
||||
"representation. Want independent copy of element data.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSet(t *testing.T) {
|
||||
s := "1 2 3\n4 5 6\n7 8 9"
|
||||
m, err := New(s)
|
||||
if err != nil {
|
||||
t.Skip("Need working New for TestSet")
|
||||
}
|
||||
xr := [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
|
||||
if !reflect.DeepEqual(m.Rows(), xr) {
|
||||
t.Skip("Need working Rows for TestSet")
|
||||
}
|
||||
xc := [][]int{{1, 4, 7}, {2, 5, 8}, {3, 6, 9}}
|
||||
if !reflect.DeepEqual(m.Cols(), xc) {
|
||||
t.Skip("Need working Cols for TestSet")
|
||||
}
|
||||
// test each corner, each side, and an interior element
|
||||
for r := 0; r < 3; r++ {
|
||||
for c := 0; c < 3; c++ {
|
||||
m, _ = New(s)
|
||||
val := 10 + r*3 + c
|
||||
if ok := m.Set(r, c, val); !ok {
|
||||
t.Fatalf("Matrix(%q).Set(%d, %d, %d) returned !ok, want ok.",
|
||||
s, r, c, val)
|
||||
}
|
||||
xr = [][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
|
||||
xc = [][]int{{1, 4, 7}, {2, 5, 8}, {3, 6, 9}}
|
||||
xr[r][c] = val
|
||||
xc[c][r] = val
|
||||
if res := m.Rows(); !reflect.DeepEqual(res, xr) {
|
||||
t.Fatalf("Matrix(%q).Set(%d, %d, %d), Rows() = %v, want %v",
|
||||
s, r, c, val, res, xr)
|
||||
}
|
||||
if res := m.Cols(); !reflect.DeepEqual(res, xc) {
|
||||
t.Fatalf("Matrix(%q).Set(%d, %d, %d), Cols() = %v, want %v",
|
||||
s, r, c, val, res, xc)
|
||||
}
|
||||
}
|
||||
}
|
||||
// test 1 and 2 off each corner and side
|
||||
m, _ = New(s)
|
||||
for _, r := range []int{-2, -1, 0, 3, 4} {
|
||||
for _, c := range []int{-2, -1, 0, 3, 4} {
|
||||
if r == 0 && c == 0 {
|
||||
continue
|
||||
}
|
||||
if ok := m.Set(r, c, 0); ok {
|
||||
t.Fatalf("Matrix(%q).Set(%d, %d, 0) = ok, want !ok", s, r, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
45
go/nucleotide-count/README.md
Normal file
45
go/nucleotide-count/README.md
Normal file
@ -0,0 +1,45 @@
|
||||
# Nucleotide Count
|
||||
|
||||
Given a DNA string, compute how many times each nucleotide occurs in the string.
|
||||
|
||||
DNA is represented by an alphabet of the following symbols: 'A', 'C',
|
||||
'G', and 'T'.
|
||||
|
||||
Each symbol represents a nucleotide, which is a fancy name for the
|
||||
particular molecules that happen to make up a large part of DNA.
|
||||
|
||||
Shortest intro to biochemistry EVAR:
|
||||
|
||||
- twigs are to birds nests as
|
||||
- nucleotides are to DNA and RNA as
|
||||
- amino acids are to proteins as
|
||||
- sugar is to starch as
|
||||
- oh crap lipids
|
||||
|
||||
I'm not going to talk about lipids because they're crazy complex.
|
||||
|
||||
So back to nucleotides.
|
||||
|
||||
DNA contains four types of them: adenine (`A`), cytosine (`C`), guanine
|
||||
(`G`), and thymine (`T`).
|
||||
|
||||
RNA contains a slightly different set of nucleotides, but we don't care
|
||||
about that for now.
|
||||
|
||||
To run the tests simply run the command `go test` in the exercise directory.
|
||||
|
||||
If the test suite contains benchmarks, you can run these with the `-bench`
|
||||
flag:
|
||||
|
||||
go test -bench .
|
||||
|
||||
For more detailed info about the Go track see the [help
|
||||
page](http://exercism.io/languages/go).
|
||||
|
||||
## Source
|
||||
|
||||
The Calculating DNA Nucleotides_problem at Rosalind [http://rosalind.info/problems/dna/](http://rosalind.info/problems/dna/)
|
||||
|
||||
## Submitting Incomplete Problems
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
||||
|
38
go/nucleotide-count/dna.go
Normal file
38
go/nucleotide-count/dna.go
Normal file
@ -0,0 +1,38 @@
|
||||
package dna
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Histogram is just a map
|
||||
type Histogram map[byte]int
|
||||
|
||||
// DNAProc is a struct that holds a dna strand
|
||||
type DNAProc struct {
|
||||
strand string
|
||||
}
|
||||
|
||||
// DNA is the function that creates DNAProcs
|
||||
func DNA(st string) *DNAProc {
|
||||
return &DNAProc{strand: st}
|
||||
}
|
||||
|
||||
// Count takes a nucleotide byte and returns how many there are
|
||||
// or an error if it's an invalid nucleotide
|
||||
func (d *DNAProc) Count(n byte) (int, error) {
|
||||
if n != 'A' && n != 'C' && n != 'G' && n != 'T' {
|
||||
return 0, errors.New("Invalid Nucleotide " + string(n))
|
||||
}
|
||||
return strings.Count(d.strand, string(n)), nil
|
||||
}
|
||||
|
||||
// Counts returns a Histogram of all nucleotide counts
|
||||
func (d *DNAProc) Counts() Histogram {
|
||||
h := make(Histogram)
|
||||
h['A'], _ = d.Count('A')
|
||||
h['C'], _ = d.Count('C')
|
||||
h['G'], _ = d.Count('G')
|
||||
h['T'], _ = d.Count('T')
|
||||
return h
|
||||
}
|
108
go/nucleotide-count/nucleotide_count_test.go
Normal file
108
go/nucleotide-count/nucleotide_count_test.go
Normal file
@ -0,0 +1,108 @@
|
||||
package dna
|
||||
|
||||
import "testing"
|
||||
|
||||
func (h Histogram) Equal(o Histogram) bool {
|
||||
return h.sameLength(o) && h.sameMappings(o)
|
||||
}
|
||||
|
||||
func (h Histogram) sameLength(o Histogram) bool {
|
||||
return len(h) == len(o)
|
||||
}
|
||||
|
||||
func (h Histogram) sameMappings(o Histogram) (res bool) {
|
||||
res = true
|
||||
for k := range h {
|
||||
if h[k] != o[k] {
|
||||
res = false
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var tallyTests = []struct {
|
||||
strand string
|
||||
nucleotide byte
|
||||
expected int
|
||||
}{
|
||||
{"", 'A', 0},
|
||||
{"ACT", 'G', 0},
|
||||
{"CCCCC", 'C', 5},
|
||||
{"GGGGGTAACCCGG", 'T', 1},
|
||||
}
|
||||
|
||||
func TestNucleotideCounts(t *testing.T) {
|
||||
for _, tt := range tallyTests {
|
||||
dna := DNA(tt.strand)
|
||||
count, _ := dna.Count(tt.nucleotide)
|
||||
if count != tt.expected {
|
||||
t.Fatalf("Got \"%v\", expected \"%v\"", count, tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHasErrorForInvalidNucleotides(t *testing.T) {
|
||||
dna := DNA("GATTACA")
|
||||
count, err := dna.Count('X')
|
||||
if count != 0 {
|
||||
t.Fatalf("Got \"%v\", expected \"%v\"", count, 0)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatalf("X is an invalid nucleotide, but no error was raised")
|
||||
}
|
||||
}
|
||||
|
||||
// In most cases, this test is pointless.
|
||||
// Very occasionally it matters.
|
||||
// Just roll with it.
|
||||
func TestCountingDoesntChangeCount(t *testing.T) {
|
||||
dna := DNA("CGATTGGG")
|
||||
dna.Count('T')
|
||||
count, _ := dna.Count('T')
|
||||
if count != 2 {
|
||||
t.Fatalf("Got \"%v\", expected \"%v\"", count, 2)
|
||||
}
|
||||
}
|
||||
|
||||
type histogramTest struct {
|
||||
strand string
|
||||
expected Histogram
|
||||
}
|
||||
|
||||
var histogramTests = []histogramTest{
|
||||
{
|
||||
"",
|
||||
Histogram{'A': 0, 'C': 0, 'T': 0, 'G': 0},
|
||||
},
|
||||
{
|
||||
"GGGGGGGG",
|
||||
Histogram{'A': 0, 'C': 0, 'T': 0, 'G': 8},
|
||||
},
|
||||
{
|
||||
"AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC",
|
||||
Histogram{'A': 20, 'C': 12, 'T': 21, 'G': 17},
|
||||
},
|
||||
}
|
||||
|
||||
func TestSequenceHistograms(t *testing.T) {
|
||||
for _, tt := range histogramTests {
|
||||
dna := DNA(tt.strand)
|
||||
if !dna.Counts().Equal(tt.expected) {
|
||||
t.Fatalf("DNA{ \"%v\" }: Got \"%v\", expected \"%v\"", tt.strand, dna.Counts(), tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSequenceHistograms(b *testing.B) {
|
||||
b.StopTimer()
|
||||
for _, tt := range histogramTests {
|
||||
for i := 0; i < b.N; i++ {
|
||||
dna := DNA(tt.strand)
|
||||
b.StartTimer()
|
||||
|
||||
dna.Counts()
|
||||
|
||||
b.StopTimer()
|
||||
}
|
||||
}
|
||||
}
|
41
go/wordy/wordy.go
Normal file
41
go/wordy/wordy.go
Normal file
@ -0,0 +1,41 @@
|
||||
package wordy
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Answer parses a simple word problem and returns the result
|
||||
// or false if it wasn't valid
|
||||
func Answer(inp string) (int, bool) {
|
||||
var ret int
|
||||
var operation string
|
||||
var didOperation bool
|
||||
words := strings.Fields(inp)
|
||||
for i := range words {
|
||||
tstWord := strings.Replace(words[i], "?", "", -1)
|
||||
if v, err := strconv.Atoi(tstWord); err == nil {
|
||||
switch operation {
|
||||
case "":
|
||||
ret = v
|
||||
case "plus":
|
||||
ret += v
|
||||
didOperation = true
|
||||
case "minus":
|
||||
ret -= v
|
||||
didOperation = true
|
||||
case "multiplied":
|
||||
ret *= v
|
||||
didOperation = true
|
||||
case "divided":
|
||||
ret /= v
|
||||
didOperation = true
|
||||
}
|
||||
} else {
|
||||
if words[i] == "plus" || words[i] == "minus" || words[i] == "multiplied" || words[i] == "divided" {
|
||||
operation = words[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret, didOperation
|
||||
}
|
@ -1 +1 @@
|
||||
hello-world
|
||||
example
|
37
mips/binary/README.md
Normal file
37
mips/binary/README.md
Normal file
@ -0,0 +1,37 @@
|
||||
# Binary
|
||||
|
||||
Write a program that will convert a binary number, represented as a string (e.g. '101010'), to its decimal equivalent using first principles
|
||||
|
||||
Implement binary to decimal conversion. Given a binary input
|
||||
string, your program should produce a decimal output. The
|
||||
program should handle invalid inputs.
|
||||
|
||||
## Note
|
||||
- Implement the conversion yourself.
|
||||
Do not use something else to perform the conversion for you.
|
||||
|
||||
## About Binary (Base-2)
|
||||
Decimal is a base-10 system.
|
||||
|
||||
A number 23 in base 10 notation can be understood
|
||||
as a linear combination of powers of 10:
|
||||
|
||||
- The rightmost digit gets multiplied by 10^0 = 1
|
||||
- The next number gets multiplied by 10^1 = 10
|
||||
- ...
|
||||
- The *n*th number gets multiplied by 10^*(n-1)*.
|
||||
- All these values are summed.
|
||||
|
||||
So: `23 => 2*10^1 + 3*10^0 => 2*10 + 3*1 = 23 base 10`
|
||||
|
||||
Binary is similar, but uses powers of 2 rather than powers of 10.
|
||||
|
||||
So: `101 => 1*2^2 + 0*2^1 + 1*2^0 => 1*4 + 0*2 + 1*1 => 4 + 1 => 5 base 10`.
|
||||
|
||||
## Source
|
||||
|
||||
All of Computer Science [http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-](http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-)
|
||||
|
||||
## Submitting Incomplete Problems
|
||||
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
||||
|
79
mips/binary/runner.mips
Normal file
79
mips/binary/runner.mips
Normal file
@ -0,0 +1,79 @@
|
||||
#
|
||||
# Test binary_convert with some examples
|
||||
#
|
||||
# s0 - num of tests left to run
|
||||
# s1 - address of input word
|
||||
# s2 - address of expected output word
|
||||
# s3 - char byte
|
||||
# s4 - output word
|
||||
#
|
||||
# binary_convert must:
|
||||
# - be named binary_convert and declared as global
|
||||
# - read input address of string from a0
|
||||
# - follow the convention of using the t0-9 registers for temporary storage
|
||||
# - (if it uses s0-7 then it is responsible for pushing existing values to the stack then popping them back off before returning)
|
||||
# - write integer result to v0
|
||||
|
||||
.data
|
||||
|
||||
# number of test cases
|
||||
n: .word 9
|
||||
# input values (null terminated) & expected output values (word sized ints)
|
||||
ins: .asciiz "0", "1", "10", "11", "100", "1001", "11010", "10001101000", "000011111"
|
||||
outs: .word 0, 1, 2, 3, 4, 9, 26, 1128, 31
|
||||
|
||||
failmsg: .asciiz "failed for test input: "
|
||||
okmsg: .asciiz "all tests passed"
|
||||
|
||||
|
||||
.text
|
||||
|
||||
runner:
|
||||
lw $s0, n
|
||||
la $s1, ins
|
||||
la $s2, outs
|
||||
|
||||
run_test:
|
||||
move $a0, $s1 # move address of input str to a0
|
||||
jal binary_convert # call subroutine under test
|
||||
move $v1, $v0 # move return value in v0 to v1 because we need v0 for syscall
|
||||
|
||||
lw $s4, 0($s2) # read expected output from memory
|
||||
bne $v1, $s4, exit_fail # if expected doesn't match actual, jump to fail
|
||||
|
||||
scan:
|
||||
addi $s1, $s1, 1 # move input address on byte forward
|
||||
lb $s3, 0($s1) # load byte
|
||||
beq $s3, $zero, done_scan # if char null, break loop
|
||||
j scan # loop
|
||||
|
||||
done_scan:
|
||||
addi $s1, $s1, 1 # move input address on byte past null
|
||||
|
||||
addi $s2, $s2, 4 # move to next word in output
|
||||
sub $s0, $s0, 1 # decrement num of tests left to run
|
||||
bgt $s0, $zero, run_test # if more than zero tests to run, jump to run_test
|
||||
|
||||
exit_ok:
|
||||
la $a0, okmsg # put address of okmsg into a0
|
||||
li $v0, 4 # 4 is print string
|
||||
syscall
|
||||
|
||||
li $v0, 10 # 10 is exit with zero status (clean exit)
|
||||
syscall
|
||||
|
||||
exit_fail:
|
||||
la $a0, failmsg # put address of failmsg into a0
|
||||
li $v0, 4 # 4 is print string
|
||||
syscall
|
||||
|
||||
move $a0, $s1 # print input that failed on
|
||||
li $v0, 4
|
||||
syscall
|
||||
|
||||
li $a0, 1 # set error code to 1
|
||||
li $v0, 17 # 17 is exit with error
|
||||
syscall
|
||||
|
||||
# # Include your implementation here if you wish to run this from the MARS GUI.
|
||||
# .include "impl.mips"
|
1
mips/current
Symbolic link
1
mips/current
Symbolic link
@ -0,0 +1 @@
|
||||
binary
|
1
packages/current
Symbolic link
1
packages/current
Symbolic link
@ -0,0 +1 @@
|
||||
NUnit.3.4.1
|
@ -1 +1 @@
|
||||
hello-world
|
||||
example
|
Loading…
Reference in New Issue
Block a user