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