Initialise

This commit is contained in:
Blizzard Finnegan 2025-03-09 13:26:08 -04:00
parent 3ff7f9b0b9
commit 0941f68e91
Signed by: blizzardfinnegan
GPG key ID: 61C1E13067E0018E
700 changed files with 27489 additions and 0 deletions

View file

@ -0,0 +1,43 @@
{
"blurb": "Convert a long phrase to its acronym",
"authors": [
"Akasurde"
],
"contributors": [
"alebaffa",
"antimatter96",
"bitfield",
"colinking",
"da-edra",
"ekingery",
"felixbuenemann",
"ferhatelmas",
"hilary",
"ilmanzo",
"kytrinyx",
"leenipper",
"mattcbaker",
"petertseng",
"robphoenix",
"sebito91",
"strangeman",
"tleen",
"usmanismail"
],
"files": {
"solution": [
"acronym.go"
],
"test": [
"acronym_test.go"
],
"example": [
".meta/example.go"
],
"editor": [
"cases_test.go"
]
},
"source": "Julien Vanier",
"source_url": "https://github.com/monkbroc"
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"acronym","id":"5a79933a6c1442b69e3f9b0402b81063","url":"https://exercism.org/tracks/go/exercises/acronym","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
acronym/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit acronym.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

45
acronym/README.md Normal file
View file

@ -0,0 +1,45 @@
# Acronym
Welcome to Acronym on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Convert a phrase to its acronym.
Techies love their TLA (Three Letter Acronyms)!
Help generate some jargon by writing a program that converts a long name
like Portable Network Graphics to its acronym (PNG).
## Source
### Created by
- @Akasurde
### Contributed to by
- @alebaffa
- @antimatter96
- @bitfield
- @colinking
- @da-edra
- @ekingery
- @felixbuenemann
- @ferhatelmas
- @hilary
- @ilmanzo
- @kytrinyx
- @leenipper
- @mattcbaker
- @petertseng
- @robphoenix
- @sebito91
- @strangeman
- @tleen
- @usmanismail
### Based on
Julien Vanier - https://github.com/monkbroc

15
acronym/acronym.go Normal file
View file

@ -0,0 +1,15 @@
// This is a "stub" file. It's a little start on your solution.
// It's not a complete solution though; you have to write some code.
// Package acronym should have a package comment that summarizes what it's about.
// https://golang.org/doc/effective_go.html#commentary
package acronym
// Abbreviate should have a comment documenting it.
func Abbreviate(s string) string {
// Write some code here to pass the test suite.
// Then remove all the stock comments.
// They're here to help you get started but they only clutter a finished solution.
// If you leave them in, reviewers may protest!
return ""
}

25
acronym/acronym_test.go Normal file
View file

@ -0,0 +1,25 @@
package acronym
import (
"testing"
)
func TestAcronym(t *testing.T) {
for _, test := range stringTestCases {
actual := Abbreviate(test.input)
if actual != test.expected {
t.Errorf("Acronym test [%s], expected [%s], actual [%s]", test.input, test.expected, actual)
}
}
}
func BenchmarkAcronym(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
for i := 0; i < b.N; i++ {
for _, test := range stringTestCases {
Abbreviate(test.input)
}
}
}

49
acronym/cases_test.go Normal file
View file

@ -0,0 +1,49 @@
package acronym
// Source: exercism/problem-specifications
// Commit: cacf1f1 Acronym: add underscore test case (#1436)
// Problem Specifications Version: 1.7.0
type acronymTest struct {
input string
expected string
}
var stringTestCases = []acronymTest{
{
input: "Portable Network Graphics",
expected: "PNG",
},
{
input: "Ruby on Rails",
expected: "ROR",
},
{
input: "First In, First Out",
expected: "FIFO",
},
{
input: "GNU Image Manipulation Program",
expected: "GIMP",
},
{
input: "Complementary metal-oxide semiconductor",
expected: "CMOS",
},
{
input: "Rolling On The Floor Laughing So Hard That My Dogs Came Over And Licked Me",
expected: "ROTFLSHTMDCOALM",
},
{
input: "Something - I made up from thin air",
expected: "SIMUFTA",
},
{
input: "Halley's Comet",
expected: "HC",
},
{
input: "The Road _Not_ Taken",
expected: "TRNT",
},
}

3
acronym/go.mod Normal file
View file

@ -0,0 +1,3 @@
module acronym
go 1.16

View file

@ -0,0 +1,33 @@
{
"blurb": "Convert a number, represented as a sequence of digits in one base, to any other base.",
"authors": [
"erizocosmico"
],
"contributors": [
"alebaffa",
"bitfield",
"ekingery",
"ferhatelmas",
"hilary",
"leenipper",
"ngochai94",
"petertseng",
"robphoenix",
"sebito91",
"tleen"
],
"files": {
"solution": [
"all_your_base.go"
],
"test": [
"all_your_base_test.go"
],
"example": [
".meta/example.go"
],
"editor": [
"cases_test.go"
]
}
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"all-your-base","id":"57966a5b188f41a7850b201d6599541e","url":"https://exercism.org/tracks/go/exercises/all-your-base","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
all-your-base/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit all_your_base.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

69
all-your-base/README.md Normal file
View file

@ -0,0 +1,69 @@
# All Your Base
Welcome to All Your Base on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Convert a number, represented as a sequence of digits in one base, to any other base.
Implement general base conversion. Given a number in base **a**,
represented as a sequence of digits, convert it to base **b**.
## Note
- Try to implement the conversion yourself.
Do not use something else to perform the conversion for you.
## About [Positional Notation](https://en.wikipedia.org/wiki/Positional_notation)
In positional notation, a number in base **b** can be understood as a linear
combination of powers of **b**.
The number 42, *in base 10*, means:
(4 \* 10^1) + (2 \* 10^0)
The number 101010, *in base 2*, means:
(1 \* 2^5) + (0 \* 2^4) + (1 \* 2^3) + (0 \* 2^2) + (1 \* 2^1) + (0 \* 2^0)
The number 1120, *in base 3*, means:
(1 \* 3^3) + (1 \* 3^2) + (2 \* 3^1) + (0 \* 3^0)
I think you got the idea!
*Yes. Those three numbers above are exactly the same. Congratulations!*
Assumptions:
1. Zero is always represented in outputs as [0] instead of [].
2. In no other instances are leading zeroes present in any outputs.
3. Leading zeroes are accepted in inputs.
4. An empty sequence of input digits is considered zero, rather than an error.
Handle problem cases by returning an error whose Error() method
returns one of following messages:
* input base must be >= 2
* output base must be >= 2
* all digits must satisfy 0 <= d < input base
## Source
### Created by
- @erizocosmico
### Contributed to by
- @alebaffa
- @bitfield
- @ekingery
- @ferhatelmas
- @hilary
- @leenipper
- @ngochai94
- @petertseng
- @robphoenix
- @sebito91
- @tleen

View file

@ -0,0 +1,5 @@
package allyourbase
func ConvertToBase(inputBase int, inputDigits []int, outputBase int) ([]int, error) {
panic("Please implement the ConvertToBase function")
}

View file

@ -0,0 +1,27 @@
package allyourbase
import (
"reflect"
"testing"
)
func TestConvertToBase(t *testing.T) {
for _, c := range testCases {
output, err := ConvertToBase(c.inputBase, c.inputDigits, c.outputBase)
if c.err != "" {
if err == nil || c.err != err.Error() {
t.Fatalf(`FAIL: %s
Expected error: %s
Got: %v`, c.description, c.err, err)
}
} else if !reflect.DeepEqual(c.expected, output) {
t.Fatalf(`FAIL: %s
Input base: %d
Input digits: %#v
Output base: %d
Expected output digits: %#v
Got: %#v`, c.description, c.inputBase, c.inputDigits, c.outputBase, c.expected, output)
}
t.Logf("PASS: %s", c.description)
}
}

183
all-your-base/cases_test.go Normal file
View file

@ -0,0 +1,183 @@
package allyourbase
// Source: exercism/problem-specifications
// Commit: c21ffd7 all-your-base: improve "input base is one" test
// Problem Specifications Version: 2.3.0
var testCases = []struct {
description string
inputBase int
inputDigits []int
outputBase int
expected []int
err string
}{
{
description: "single bit one to decimal",
inputBase: 2,
inputDigits: []int{1},
outputBase: 10,
expected: []int{1},
err: "",
},
{
description: "binary to single decimal",
inputBase: 2,
inputDigits: []int{1, 0, 1},
outputBase: 10,
expected: []int{5},
err: "",
},
{
description: "single decimal to binary",
inputBase: 10,
inputDigits: []int{5},
outputBase: 2,
expected: []int{1, 0, 1},
err: "",
},
{
description: "binary to multiple decimal",
inputBase: 2,
inputDigits: []int{1, 0, 1, 0, 1, 0},
outputBase: 10,
expected: []int{4, 2},
err: "",
},
{
description: "decimal to binary",
inputBase: 10,
inputDigits: []int{4, 2},
outputBase: 2,
expected: []int{1, 0, 1, 0, 1, 0},
err: "",
},
{
description: "trinary to hexadecimal",
inputBase: 3,
inputDigits: []int{1, 1, 2, 0},
outputBase: 16,
expected: []int{2, 10},
err: "",
},
{
description: "hexadecimal to trinary",
inputBase: 16,
inputDigits: []int{2, 10},
outputBase: 3,
expected: []int{1, 1, 2, 0},
err: "",
},
{
description: "15-bit integer",
inputBase: 97,
inputDigits: []int{3, 46, 60},
outputBase: 73,
expected: []int{6, 10, 45},
err: "",
},
{
description: "empty list",
inputBase: 2,
inputDigits: []int{},
outputBase: 10,
expected: []int{0},
err: "",
},
{
description: "single zero",
inputBase: 10,
inputDigits: []int{0},
outputBase: 2,
expected: []int{0},
err: "",
},
{
description: "multiple zeros",
inputBase: 10,
inputDigits: []int{0, 0, 0},
outputBase: 2,
expected: []int{0},
err: "",
},
{
description: "leading zeros",
inputBase: 7,
inputDigits: []int{0, 6, 0},
outputBase: 10,
expected: []int{4, 2},
err: "",
},
{
description: "input base is one",
inputBase: 1,
inputDigits: []int{0},
outputBase: 10,
expected: []int(nil),
err: "input base must be >= 2",
},
{
description: "input base is zero",
inputBase: 0,
inputDigits: []int{},
outputBase: 10,
expected: []int(nil),
err: "input base must be >= 2",
},
{
description: "input base is negative",
inputBase: -2,
inputDigits: []int{1},
outputBase: 10,
expected: []int(nil),
err: "input base must be >= 2",
},
{
description: "negative digit",
inputBase: 2,
inputDigits: []int{1, -1, 1, 0, 1, 0},
outputBase: 10,
expected: []int(nil),
err: "all digits must satisfy 0 <= d < input base",
},
{
description: "invalid positive digit",
inputBase: 2,
inputDigits: []int{1, 2, 1, 0, 1, 0},
outputBase: 10,
expected: []int(nil),
err: "all digits must satisfy 0 <= d < input base",
},
{
description: "output base is one",
inputBase: 2,
inputDigits: []int{1, 0, 1, 0, 1, 0},
outputBase: 1,
expected: []int(nil),
err: "output base must be >= 2",
},
{
description: "output base is zero",
inputBase: 10,
inputDigits: []int{7},
outputBase: 0,
expected: []int(nil),
err: "output base must be >= 2",
},
{
description: "output base is negative",
inputBase: 2,
inputDigits: []int{1},
outputBase: -7,
expected: []int(nil),
err: "output base must be >= 2",
},
{
description: "both bases are negative",
inputBase: -2,
inputDigits: []int{1},
outputBase: -7,
expected: []int(nil),
err: "input base must be >= 2",
},
}

3
all-your-base/go.mod Normal file
View file

@ -0,0 +1,3 @@
module allyourbase
go 1.16

View file

@ -0,0 +1,39 @@
{
"blurb": "Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.",
"authors": [
"zilkey"
],
"contributors": [
"aarti",
"alebaffa",
"bitfield",
"ekingery",
"ferhatelmas",
"hilary",
"kytrinyx",
"leenipper",
"mkoppmann",
"petertseng",
"robphoenix",
"sebito91",
"strangeman",
"tleen",
"tompao"
],
"files": {
"solution": [
"allergies.go"
],
"test": [
"allergies_test.go"
],
"example": [
".meta/example.go"
],
"editor": [
"cases_test.go"
]
},
"source": "Jumpstart Lab Warm-up",
"source_url": "http://jumpstartlab.com"
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"allergies","id":"348afc34e7dc4d0abf44316d6a081fd0","url":"https://exercism.org/tracks/go/exercises/allergies","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
allergies/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit allergies.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

63
allergies/README.md Normal file
View file

@ -0,0 +1,63 @@
# Allergies
Welcome to Allergies on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.
An allergy test produces a single numeric score which contains the
information about all the allergies the person has (that they were
tested for).
The list of items (and their value) that were tested are:
* eggs (1)
* peanuts (2)
* shellfish (4)
* strawberries (8)
* tomatoes (16)
* chocolate (32)
* pollen (64)
* cats (128)
So if Tom is allergic to peanuts and chocolate, he gets a score of 34.
Now, given just that score of 34, your program should be able to say:
* Whether Tom is allergic to any one of those allergens listed above.
* All the allergens Tom is allergic to.
Note: a given score may include allergens **not** listed above (i.e.
allergens that score 256, 512, 1024, etc.). Your program should
ignore those components of the score. For example, if the allergy
score is 257, your program should only report the eggs (1) allergy.
## Source
### Created by
- @zilkey
### Contributed to by
- @aarti
- @alebaffa
- @bitfield
- @ekingery
- @ferhatelmas
- @hilary
- @kytrinyx
- @leenipper
- @mkoppmann
- @petertseng
- @robphoenix
- @sebito91
- @strangeman
- @tleen
- @tompao
### Based on
Jumpstart Lab Warm-up - http://jumpstartlab.com

9
allergies/allergies.go Normal file
View file

@ -0,0 +1,9 @@
package allergies
func Allergies(allergies uint) []string {
panic("Please implement the Allergies function")
}
func AllergicTo(allergies uint, allergen string) bool {
panic("Please implement the AllergicTo function")
}

View file

@ -0,0 +1,79 @@
package allergies
import (
"reflect"
"testing"
)
func TestAllergies(t *testing.T) {
for _, test := range listTests {
if actual := Allergies(test.score); !sameSliceElements(actual, test.expected) {
t.Fatalf("FAIL: Allergies(%d): expected %#v, actual %#v", test.score, test.expected, actual)
} else {
t.Logf("PASS: Allergic to %#v", test.expected)
}
}
}
func BenchmarkAllergies(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
for i := 0; i < b.N; i++ {
for _, test := range allergicToTests {
Allergies(test.score)
}
}
}
func TestAllergicTo(t *testing.T) {
for _, test := range allergicToTests {
for _, response := range test.expected {
actual := AllergicTo(test.score, response.substance)
if actual != response.result {
t.Fatalf("FAIL: AllergicTo(%d, %s): expected %t, actual %t", test.score, response.substance, response.result, actual)
} else {
t.Logf("PASS: AllergicTo(%d, %s) %t", test.score, response.substance, actual)
}
}
}
}
func BenchmarkAllergicTo(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
for i := 0; i < b.N; i++ {
for _, test := range allergicToTests {
for _, response := range test.expected {
AllergicTo(test.score, response.substance)
}
}
}
}
// stringSet is a set of strings
type stringSet map[string]bool
// sameSliceElements checks if the slices have the same number of elements
// regardless of their order
func sameSliceElements(a, b []string) bool {
if len(a) != len(b) {
return false
}
return reflect.DeepEqual(sliceSet(a), sliceSet(b))
}
// sliceSet creates a new stringSet from a slice of strings
func sliceSet(list []string) stringSet {
set := make(stringSet)
for _, elem := range list {
set[elem] = true
}
return set
}

70
allergies/cases_test.go Normal file
View file

@ -0,0 +1,70 @@
package allergies
// Source: exercism/problem-specifications
// Commit: 17a2ab2 added allergies test case (#1275)
// Problem Specifications Version: 1.2.0
// allergicTo
type allergicResult struct {
substance string
result bool
}
var allergicToTests = []struct {
description string
score uint
expected []allergicResult
}{
{
description: "no allergies means not allergic",
score: 0,
expected: []allergicResult{
{"peanuts", false},
{"cats", false},
{"strawberries", false},
},
},
{
description: "is allergic to eggs",
score: 1,
expected: []allergicResult{
{"eggs", true},
},
},
{
description: "allergic to eggs in addition to other stuff",
score: 5,
expected: []allergicResult{
{"eggs", true},
{"shellfish", true},
{"strawberries", false},
},
},
{
description: "allergic to strawberries but not peanuts",
score: 9,
expected: []allergicResult{
{"eggs", true},
{"peanuts", false},
{"shellfish", false},
{"strawberries", true},
},
},
}
// list
var listTests = []struct {
description string
score uint
expected []string
}{
{"no allergies at all", 0, []string{}},
{"allergic to just eggs", 1, []string{"eggs"}},
{"allergic to just peanuts", 2, []string{"peanuts"}},
{"allergic to just strawberries", 8, []string{"strawberries"}},
{"allergic to eggs and peanuts", 3, []string{"eggs", "peanuts"}},
{"allergic to more than eggs but not peanuts", 5, []string{"eggs", "shellfish"}},
{"allergic to lots of stuff", 248, []string{"strawberries", "tomatoes", "chocolate", "pollen", "cats"}},
{"allergic to everything", 255, []string{"eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"}},
{"ignore non allergen score parts", 509, []string{"eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"}},
}

3
allergies/go.mod Normal file
View file

@ -0,0 +1,3 @@
module allergies
go 1.16

View file

@ -0,0 +1,41 @@
{
"blurb": "Given a word and a list of possible anagrams, select the correct sublist.",
"authors": [
"mikegehard"
],
"contributors": [
"alebaffa",
"bitfield",
"ekingery",
"ferhatelmas",
"henrik",
"hilary",
"ilmanzo",
"kf8a",
"kytrinyx",
"leenipper",
"markijbema",
"petertseng",
"robphoenix",
"sebito91",
"strangeman",
"tleen",
"tompao"
],
"files": {
"solution": [
"anagram.go"
],
"test": [
"anagram_test.go"
],
"example": [
".meta/example.go"
],
"editor": [
"cases_test.go"
]
},
"source": "Inspired by the Extreme Startup game",
"source_url": "https://github.com/rchatley/extreme_startup"
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"anagram","id":"984fe85be7224a63a97367cb9680f24f","url":"https://exercism.org/tracks/go/exercises/anagram","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
anagram/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit anagram.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

43
anagram/README.md Normal file
View file

@ -0,0 +1,43 @@
# Anagram
Welcome to Anagram on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
An anagram is a rearrangement of letters to form a new word.
Given a word and a list of candidates, select the sublist of anagrams of the given word.
Given `"listen"` and a list of candidates like `"enlists" "google"
"inlets" "banana"` the program should return a list containing
`"inlets"`.
## Source
### Created by
- @mikegehard
### Contributed to by
- @alebaffa
- @bitfield
- @ekingery
- @ferhatelmas
- @henrik
- @hilary
- @ilmanzo
- @kf8a
- @kytrinyx
- @leenipper
- @markijbema
- @petertseng
- @robphoenix
- @sebito91
- @strangeman
- @tleen
- @tompao
### Based on
Inspired by the Extreme Startup game - https://github.com/rchatley/extreme_startup

5
anagram/anagram.go Normal file
View file

@ -0,0 +1,5 @@
package anagram
func Detect(subject string, candidates []string) []string {
panic("Please implement the Detect function")
}

45
anagram/anagram_test.go Normal file
View file

@ -0,0 +1,45 @@
package anagram
import (
"fmt"
"sort"
"testing"
)
func equal(a, b []string) bool {
if len(b) != len(a) {
return false
}
sort.Strings(a)
sort.Strings(b)
return fmt.Sprintf("%v", a) == fmt.Sprintf("%v", b)
}
func TestDetectAnagrams(t *testing.T) {
for _, tt := range testCases {
actual := Detect(tt.subject, tt.candidates)
if !equal(tt.expected, actual) {
msg := `FAIL: %s
Subject %s
Candidates %q
Expected %q
Got %q
`
t.Fatalf(msg, tt.description, tt.subject, tt.candidates, tt.expected, actual)
} else {
t.Logf("PASS: %s", tt.description)
}
}
}
func BenchmarkDetectAnagrams(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
for i := 0; i < b.N; i++ {
for _, tt := range testCases {
Detect(tt.subject, tt.candidates)
}
}
}

128
anagram/cases_test.go Normal file
View file

@ -0,0 +1,128 @@
package anagram
// Source: exercism/problem-specifications
// Commit: baaf092 anagram: words are not anagrams of themselves
// Problem Specifications Version: 1.4.0
var testCases = []struct {
description string
subject string
candidates []string
expected []string
}{
{
description: "no matches",
subject: "diaper",
candidates: []string{
"hello",
"world",
"zombies",
"pants"},
expected: []string{},
},
{
description: "detects two anagrams",
subject: "master",
candidates: []string{
"stream",
"pigeon",
"maters"},
expected: []string{
"stream",
"maters"},
},
{
description: "does not detect anagram subsets",
subject: "good",
candidates: []string{
"dog",
"goody"},
expected: []string{},
},
{
description: "detects anagram",
subject: "listen",
candidates: []string{
"enlists",
"google",
"inlets",
"banana"},
expected: []string{
"inlets"},
},
{
description: "detects three anagrams",
subject: "allergy",
candidates: []string{
"gallery",
"ballerina",
"regally",
"clergy",
"largely",
"leading"},
expected: []string{
"gallery",
"regally",
"largely"},
},
{
description: "does not detect non-anagrams with identical checksum",
subject: "mass",
candidates: []string{
"last"},
expected: []string{},
},
{
description: "detects anagrams case-insensitively",
subject: "Orchestra",
candidates: []string{
"cashregister",
"Carthorse",
"radishes"},
expected: []string{
"Carthorse"},
},
{
description: "detects anagrams using case-insensitive subject",
subject: "Orchestra",
candidates: []string{
"cashregister",
"carthorse",
"radishes"},
expected: []string{
"carthorse"},
},
{
description: "detects anagrams using case-insensitive possible matches",
subject: "orchestra",
candidates: []string{
"cashregister",
"Carthorse",
"radishes"},
expected: []string{
"Carthorse"},
},
{
description: "does not detect a anagram if the original word is repeated",
subject: "go",
candidates: []string{
"go Go GO"},
expected: []string{},
},
{
description: "anagrams must use all letters exactly once",
subject: "tapper",
candidates: []string{
"patter"},
expected: []string{},
},
{
description: "words are not anagrams of themselves (case-insensitive)",
subject: "BANANA",
candidates: []string{
"BANANA",
"Banana",
"banana"},
expected: []string{},
},
}

3
anagram/go.mod Normal file
View file

@ -0,0 +1,3 @@
module anagram
go 1.16

View file

@ -0,0 +1,33 @@
{
"blurb": "Determine if a number is an Armstrong number",
"authors": [
"ilmanzo"
],
"contributors": [
"bitfield",
"da-edra",
"Daveed9",
"ekingery",
"ferhatelmas",
"hilary",
"kytrinyx",
"leenipper",
"sebito91"
],
"files": {
"solution": [
"armstrong_numbers.go"
],
"test": [
"armstrong_numbers_test.go"
],
"example": [
".meta/example.go"
],
"editor": [
"cases_test.go"
]
},
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Narcissistic_number"
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"armstrong-numbers","id":"e257645217454209b478764ad41df2ef","url":"https://exercism.org/tracks/go/exercises/armstrong-numbers","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
armstrong-numbers/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit armstrong_numbers.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

View file

@ -0,0 +1,39 @@
# Armstrong Numbers
Welcome to Armstrong Numbers on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
An [Armstrong number](https://en.wikipedia.org/wiki/Narcissistic_number) is a number that is the sum of its own digits each raised to the power of the number of digits.
For example:
- 9 is an Armstrong number, because `9 = 9^1 = 9`
- 10 is *not* an Armstrong number, because `10 != 1^2 + 0^2 = 1`
- 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153`
- 154 is *not* an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190`
Write some code to determine whether a number is an Armstrong number.
## Source
### Created by
- @ilmanzo
### Contributed to by
- @bitfield
- @da-edra
- @Daveed9
- @ekingery
- @ferhatelmas
- @hilary
- @kytrinyx
- @leenipper
- @sebito91
### Based on
Wikipedia - https://en.wikipedia.org/wiki/Narcissistic_number

View file

@ -0,0 +1,5 @@
package armstrong
func IsNumber(n int) bool {
panic("Please implement the IsNumber function")
}

View file

@ -0,0 +1,28 @@
package armstrong
import (
"fmt"
"testing"
)
func TestArmstrong(t *testing.T) {
for _, tc := range testCases {
if actual := IsNumber(tc.input); actual != tc.expected {
t.Fatalf("FAIL: %s\nExpected: %v\nActual: %v", tc.description, tc.expected, actual)
}
t.Logf("PASS: %s", tc.description)
}
}
func BenchmarkIsNumber(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
for _, tc := range testCases {
b.Run(fmt.Sprintf("%d", tc.input), func(b *testing.B) {
for i := 0; i < b.N; i++ {
IsNumber(tc.input)
}
})
}
}

View file

@ -0,0 +1,57 @@
package armstrong
// Source: exercism/problem-specifications
// Commit: b3c2522 armstrong-numbers: Zero is an Armstrong number and requires specific testing (#1505)
// Problem Specifications Version: 1.1.0
var testCases = []struct {
description string
input int
expected bool
}{
{
description: "Zero is an Armstrong number",
input: 0,
expected: true,
},
{
description: "Single digit numbers are Armstrong numbers",
input: 5,
expected: true,
},
{
description: "There are no 2 digit Armstrong numbers",
input: 10,
expected: false,
},
{
description: "Three digit number that is an Armstrong number",
input: 153,
expected: true,
},
{
description: "Three digit number that is not an Armstrong number",
input: 100,
expected: false,
},
{
description: "Four digit number that is an Armstrong number",
input: 9474,
expected: true,
},
{
description: "Four digit number that is not an Armstrong number",
input: 9475,
expected: false,
},
{
description: "Seven digit number that is an Armstrong number",
input: 9926315,
expected: true,
},
{
description: "Seven digit number that is not an Armstrong number",
input: 9926314,
expected: false,
},
}

3
armstrong-numbers/go.mod Normal file
View file

@ -0,0 +1,3 @@
module armstrong
go 1.16

View file

@ -0,0 +1,37 @@
{
"blurb": "Create an implementation of the atbash cipher, an ancient encryption system created in the Middle East.",
"authors": [
"zilkey"
],
"contributors": [
"alebaffa",
"bitfield",
"ekingery",
"ferhatelmas",
"hilary",
"kytrinyx",
"leenipper",
"petertseng",
"robphoenix",
"sebito91",
"strangeman",
"tleen",
"tompao"
],
"files": {
"solution": [
"atbash_cipher.go"
],
"test": [
"atbash_cipher_test.go"
],
"example": [
".meta/example.go"
],
"editor": [
"cases_test.go"
]
},
"source": "Wikipedia",
"source_url": "http://en.wikipedia.org/wiki/Atbash"
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"atbash-cipher","id":"7ab13ce7aca04d1e868f8547d6c7fec9","url":"https://exercism.org/tracks/go/exercises/atbash-cipher","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
atbash-cipher/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit atbash_cipher.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

60
atbash-cipher/README.md Normal file
View file

@ -0,0 +1,60 @@
# Atbash Cipher
Welcome to Atbash Cipher on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Create an implementation of the atbash cipher, an ancient encryption system created in the Middle East.
The Atbash cipher is a simple substitution cipher that relies on
transposing all the letters in the alphabet such that the resulting
alphabet is backwards. The first letter is replaced with the last
letter, the second with the second-last, and so on.
An Atbash cipher for the Latin alphabet would be as follows:
```text
Plain: abcdefghijklmnopqrstuvwxyz
Cipher: zyxwvutsrqponmlkjihgfedcba
```
It is a very weak cipher because it only has one possible key, and it is
a simple mono-alphabetic substitution cipher. However, this may not have
been an issue in the cipher's time.
Ciphertext is written out in groups of fixed length, the traditional group size
being 5 letters, and punctuation is excluded. This is to make it harder to guess
things based on word boundaries.
## Examples
- Encoding `test` gives `gvhg`
- Decoding `gvhg` gives `test`
- Decoding `gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt` gives `thequickbrownfoxjumpsoverthelazydog`
## Source
### Created by
- @zilkey
### Contributed to by
- @alebaffa
- @bitfield
- @ekingery
- @ferhatelmas
- @hilary
- @kytrinyx
- @leenipper
- @petertseng
- @robphoenix
- @sebito91
- @strangeman
- @tleen
- @tompao
### Based on
Wikipedia - http://en.wikipedia.org/wiki/Atbash

View file

@ -0,0 +1,5 @@
package atbash
func Atbash(s string) string {
panic("Please implement the Atbash function")
}

View file

@ -0,0 +1,25 @@
package atbash
import "testing"
func TestAtbash(t *testing.T) {
for _, test := range tests {
actual := Atbash(test.s)
if actual != test.expected {
t.Errorf("Atbash('%s'): expected '%s', actual '%s'", test.s, test.expected, actual)
}
}
}
func BenchmarkAtbash(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
for i := 0; i < b.N; i++ {
for _, test := range tests {
Atbash(test.s)
}
}
}

View file

@ -0,0 +1,61 @@
package atbash
// Source: exercism/problem-specifications
// Commit: dda678b atbash-cipher: Apply new "input" policy
// Problem Specifications Version: 1.1.0
type atbashTest struct {
s string
expected string
}
var tests = []atbashTest{
{
s: "yes",
expected: "bvh",
},
{
s: "no",
expected: "ml",
},
{
s: "OMG",
expected: "lnt",
},
{
s: "O M G",
expected: "lnt",
},
{
s: "mindblowingly",
expected: "nrmwy oldrm tob",
},
{
s: "Testing,1 2 3, testing.",
expected: "gvhgr mt123 gvhgr mt",
},
{
s: "Truth is fiction.",
expected: "gifgs rhurx grlm",
},
{
s: "The quick brown fox jumps over the lazy dog.",
expected: "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt",
},
{
s: "exercism",
expected: "vcvix rhn",
},
{
s: "anobstacleisoftenasteppingstone",
expected: "zmlyh gzxov rhlug vmzhg vkkrm thglm v",
},
{
s: "testing123testing",
expected: "gvhgr mt123 gvhgr mt",
},
{
s: "thequickbrownfoxjumpsoverthelazydog",
expected: "gsvjf rxpyi ldmul cqfnk hlevi gsvoz abwlt",
},
}

3
atbash-cipher/go.mod Normal file
View file

@ -0,0 +1,3 @@
module atbash
go 1.16

View file

@ -0,0 +1,34 @@
{
"blurb": "Simulate a bank account supporting opening/closing, withdraws, and deposits of money. Watch out for concurrent transactions!",
"authors": [
"soniakeys"
],
"contributors": [
"alebaffa",
"bitfield",
"ekingery",
"ferhatelmas",
"hilary",
"homelinen",
"JensChrG",
"juergenhoetzel",
"kytrinyx",
"leenipper",
"parroty",
"petertseng",
"robphoenix",
"sebito91",
"tleen"
],
"files": {
"solution": [
"bank_account.go"
],
"test": [
"bank_account_test.go"
],
"example": [
".meta/example.go"
]
}
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"bank-account","id":"144a1c0f54a6427297f78eb8112d5bf8","url":"https://exercism.org/tracks/go/exercises/bank-account","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
bank-account/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit bank_account.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

77
bank-account/README.md Normal file
View file

@ -0,0 +1,77 @@
# Bank Account
Welcome to Bank Account on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Simulate a bank account supporting opening/closing, withdrawals, and deposits
of money. Watch out for concurrent transactions!
A bank account can be accessed in multiple ways. Clients can make
deposits and withdrawals using the internet, mobile phones, etc. Shops
can charge against the account.
Create an account that can be accessed from multiple threads/processes
(terminology depends on your programming language).
It should be possible to close an account; operations against a closed
account must fail.
## Instructions
Run the test file, and fix each of the errors in turn. When you get the
first test to pass, go to the first pending or skipped test, and make
that pass as well. When all of the tests are passing, feel free to
submit.
Remember that passing code is just the first step. The goal is to work
towards a solution that is as readable and expressive as you can make
it.
Have fun!
## Implementation Notes
If Open is given a negative initial deposit, it must return nil.
Deposit must handle a negative amount as a withdrawal. Withdrawals must
not succeed if they result in a negative balance.
If any Account method is called on an closed account, it must not modify
the account and must return ok = false.
The tests will execute some operations concurrently. You should strive
to ensure that operations on the Account leave it in a consistent state.
For example: multiple goroutines may be depositing and withdrawing money
simultaneously, two withdrawals occurring concurrently should not be able
to bring the balance into the negative.
If you are new to concurrent operations in Go it will be worth looking
at the sync package, specifically Mutexes:
https://golang.org/pkg/sync/
https://tour.golang.org/concurrency/9
https://gobyexample.com/mutexes
## Source
### Created by
- @soniakeys
### Contributed to by
- @alebaffa
- @bitfield
- @ekingery
- @ferhatelmas
- @hilary
- @homelinen
- @JensChrG
- @juergenhoetzel
- @kytrinyx
- @leenipper
- @parroty
- @petertseng
- @robphoenix
- @sebito91
- @tleen

View file

@ -0,0 +1,19 @@
package account
// Define the Account type here.
func Open(amount int64) *Account {
panic("Please implement the Open function")
}
func (a *Account) Balance() (int64, bool) {
panic("Please implement the Balance function")
}
func (a *Account) Deposit(amount int64) (int64, bool) {
panic("Please implement the Deposit function")
}
func (a *Account) Close() (int64, bool) {
panic("Please implement the Close function")
}

View file

@ -0,0 +1,334 @@
package account
import (
"runtime"
"sync"
"sync/atomic"
"testing"
"time"
)
func TestSeqOpenBalanceClose(t *testing.T) {
// open account
const amt = 10
a := Open(amt)
if a == nil {
t.Fatalf("Open(%d) = nil, want non-nil *Account.", amt)
}
t.Logf("Account 'a' opened with initial balance of %d.", amt)
// verify balance after open
switch b, ok := a.Balance(); {
case !ok:
t.Fatal("a.Balance() returned !ok, want ok.")
case b != amt:
t.Fatalf("a.Balance() = %d, want %d", b, amt)
}
// close account
switch p, ok := a.Close(); {
case !ok:
t.Fatalf("a.Close() returned !ok, want ok.")
case p != amt:
t.Fatalf("a.Close() returned payout = %d, want %d.", p, amt)
}
t.Log("Account 'a' closed.")
// verify balance no longer accessible
if b, ok := a.Balance(); ok {
t.Log("Balance still available on closed account.")
t.Fatalf("a.Balance() = %d, %t. Want ok == false", b, ok)
}
// verify closing balance is 0
if b, _ := a.Balance(); b != 0 {
t.Log("Balance after close is non-zero.")
t.Fatalf("After a.Close() balance is %d and not 0", b)
}
}
func TestSeqOpenDepositClose(t *testing.T) {
// open account
const openAmt = 10
a := Open(openAmt)
if a == nil {
t.Fatalf("Open(%d) = nil, want non-nil *Account.", openAmt)
}
t.Logf("Account 'a' opened with initial balance of %d.", openAmt)
// deposit
const depAmt = 20
const newAmt = openAmt + depAmt
switch b, ok := a.Deposit(depAmt); {
case !ok:
t.Fatalf("a.Deposit(%d) returned !ok, want ok.", depAmt)
case b != openAmt+depAmt:
t.Fatalf("a.Deposit(%d) = %d, want new balance = %d", depAmt, b, newAmt)
}
t.Logf("Deposit of %d accepted to account 'a'", depAmt)
// close account
switch p, ok := a.Close(); {
case !ok:
t.Fatalf("a.Close() returned !ok, want ok.")
case p != newAmt:
t.Fatalf("a.Close() returned payout = %d, want %d.", p, newAmt)
}
t.Log("Account 'a' closed.")
// verify deposits no longer accepted
if b, ok := a.Deposit(1); ok {
t.Log("Deposit accepted on closed account.")
t.Fatalf("a.Deposit(1) = %d, %t. Want ok == false", b, ok)
}
}
func TestMoreSeqCases(t *testing.T) {
// open account 'a' as before
const openAmt = 10
a := Open(openAmt)
if a == nil {
t.Fatalf("Open(%d) = nil, want non-nil *Account.", openAmt)
}
t.Logf("Account 'a' opened with initial balance of %d.", openAmt)
// open account 'z' with zero balance
z := Open(0)
if z == nil {
t.Fatal("Open(0) = nil, want non-nil *Account.")
}
t.Log("Account 'z' opened with initial balance of 0.")
// attempt to open account with negative opening balance
if Open(-10) != nil {
t.Fatal("Open(-10) seemed to work, " +
"want nil result for negative opening balance.")
}
// verify both balances a and z still there
switch b, ok := a.Balance(); {
case !ok:
t.Fatal("a.Balance() returned !ok, want ok.")
case b != openAmt:
t.Fatalf("a.Balance() = %d, want %d", b, openAmt)
}
switch b, ok := z.Balance(); {
case !ok:
t.Fatal("z.Balance() returned !ok, want ok.")
case b != 0:
t.Fatalf("z.Balance() = %d, want 0", b)
}
// withdrawals
const wAmt = 3
const newAmt = openAmt - wAmt
switch b, ok := a.Deposit(-wAmt); {
case !ok:
t.Fatalf("a.Deposit(%d) returned !ok, want ok.", -wAmt)
case b != newAmt:
t.Fatalf("a.Deposit(%d) = %d, want new balance = %d", -wAmt, b, newAmt)
}
t.Logf("Withdrawal of %d accepted from account 'a'", wAmt)
if _, ok := z.Deposit(-1); ok {
t.Fatal("z.Deposit(-1) returned ok, want !ok.")
}
// verify both balances
switch b, ok := a.Balance(); {
case !ok:
t.Fatal("a.Balance() returned !ok, want ok.")
case b != newAmt:
t.Fatalf("a.Balance() = %d, want %d", b, newAmt)
}
switch b, ok := z.Balance(); {
case !ok:
t.Fatal("z.Balance() returned !ok, want ok.")
case b != 0:
t.Fatalf("z.Balance() = %d, want 0", b)
}
// close just z
switch p, ok := z.Close(); {
case !ok:
t.Fatalf("z.Close() returned !ok, want ok.")
case p != 0:
t.Fatalf("z.Close() returned payout = %d, want 0.", p)
}
t.Log("Account 'z' closed.")
// verify 'a' balance one more time
switch b, ok := a.Balance(); {
case !ok:
t.Fatal("a.Balance() returned !ok, want ok.")
case b != newAmt:
t.Fatalf("a.Balance() = %d, want %d", b, newAmt)
}
}
func TestConcClose(t *testing.T) {
if runtime.NumCPU() < 2 {
t.Skip("Multiple CPU cores required for concurrency tests.")
}
if runtime.GOMAXPROCS(0) < 2 {
runtime.GOMAXPROCS(2)
}
// test competing close attempts
for rep := 0; rep < 1000; rep++ {
const openAmt = 10
a := Open(openAmt)
if a == nil {
t.Fatalf("Open(%d) = nil, want non-nil *Account.", openAmt)
}
var start sync.WaitGroup
start.Add(1)
const closeAttempts = 10
res := make(chan string)
for i := 0; i < closeAttempts; i++ {
go func() { // on your mark,
start.Wait() // get set...
switch p, ok := a.Close(); {
case !ok:
if p != 0 {
t.Errorf("a.Close() = %d, %t. "+
"Want payout = 0 for unsuccessful close", p, ok)
res <- "fail"
} else {
res <- "already closed"
}
case p != openAmt:
t.Errorf("a.Close() = %d, %t. "+
"Want payout = %d for successful close", p, ok, openAmt)
res <- "fail"
default:
res <- "close" // exactly one goroutine should reach here
}
}()
}
start.Done() // ...go
var closes, fails int
for i := 0; i < closeAttempts; i++ {
switch <-res {
case "close":
closes++
case "fail":
fails++
}
}
switch {
case fails > 0:
t.FailNow() // error already logged by other goroutine
case closes == 0:
t.Fatal("Concurrent a.Close() attempts all failed. " +
"Want one to succeed.")
case closes > 1:
t.Fatalf("%d concurrent a.Close() attempts succeeded, "+
"each paying out %d!. Want just one to succeed.",
closes, openAmt)
}
}
}
func TestConcDeposit(t *testing.T) {
if runtime.NumCPU() < 2 {
t.Skip("Multiple CPU cores required for concurrency tests.")
}
if runtime.GOMAXPROCS(0) < 2 {
runtime.GOMAXPROCS(2)
}
a := Open(0)
if a == nil {
t.Fatal("Open(0) = nil, want non-nil *Account.")
}
const amt = 10
const c = 1000
var negBal int32
var start, g sync.WaitGroup
start.Add(1)
g.Add(3 * c)
for i := 0; i < c; i++ {
go func() { // deposit
start.Wait()
a.Deposit(amt) // ignore return values
g.Done()
}()
go func() { // withdraw
start.Wait()
for {
if _, ok := a.Deposit(-amt); ok {
break
}
time.Sleep(time.Microsecond) // retry
}
g.Done()
}()
go func() { // watch that balance stays >= 0
start.Wait()
if p, _ := a.Balance(); p < 0 {
atomic.StoreInt32(&negBal, 1)
}
g.Done()
}()
}
start.Done()
g.Wait()
if negBal == 1 {
t.Fatal("Balance went negative with concurrent deposits and " +
"withdrawals. Want balance always >= 0.")
}
if p, ok := a.Balance(); !ok || p != 0 {
t.Fatalf("After equal concurrent deposits and withdrawals, "+
"a.Balance = %d, %t. Want 0, true", p, ok)
}
}
// The benchmark operations are here to encourage you to try different
// implementations to see which ones perform better. These are worth
// exploring after the tests pass.
//
// There is a basic benchmark and a parallelized version of the same
// benchmark. You run the benchmark using:
// go test --bench=.
//
// The output will look something like this:
// goos: linux
// goarch: amd64
// BenchmarkAccountOperations-8 10000000 130 ns/op
// BenchmarkAccountOperationsParallel-8 3000000 488 ns/op
// PASS
//
// You will notice that parallelism does not increase speed in this case, in
// fact it makes things slower! This is because none of the operations in our
// Account benefit from parallel processing. We are specifically protecting
// the account balance internals from being accessed by multiple processes
// simultaneously. Your protections will make the parallel processing slower
// because there is some overhead in managing the processes and protections.
//
// The interesting thing to try here is to experiment with the protections
// and see how their implementation changes the results of the parallel
// benchmark.
func BenchmarkAccountOperations(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
a := Open(0)
defer a.Close()
for n := 0; n < b.N; n++ {
a.Deposit(10)
a.Deposit(-10)
}
}
func BenchmarkAccountOperationsParallel(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
a := Open(0)
defer a.Close()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
a.Deposit(10)
a.Deposit(-10)
}
})
}

3
bank-account/go.mod Normal file
View file

@ -0,0 +1,3 @@
module account
go 1.16

View file

@ -0,0 +1,35 @@
{
"blurb": "Insert and search for numbers in a binary tree.",
"authors": [
"zilkey"
],
"contributors": [
"alebaffa",
"bitfield",
"ekingery",
"ferhatelmas",
"hilary",
"jcbwlkr",
"kytrinyx",
"leenipper",
"petertseng",
"robphoenix",
"sebito91",
"sjakobi",
"tapank",
"tleen"
],
"files": {
"solution": [
"binary_search_tree.go"
],
"test": [
"binary_search_tree_test.go"
],
"example": [
".meta/example.go"
]
},
"source": "Josh Cheek",
"source_url": "https://twitter.com/josh_cheek"
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"binary-search-tree","id":"d27006c8034b45b484a392abb1b5adc8","url":"https://exercism.org/tracks/go/exercises/binary-search-tree","handle":"snowyforest","is_requester":true,"auto_approve":false}

View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit binary_search_tree.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

View file

@ -0,0 +1,86 @@
# Binary Search Tree
Welcome to Binary Search Tree on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Insert and search for numbers in a binary tree.
When we need to represent sorted data, an array does not make a good
data structure.
Say we have the array `[1, 3, 4, 5]`, and we add 2 to it so it becomes
`[1, 3, 4, 5, 2]` now we must sort the entire array again! We can
improve on this by realizing that we only need to make space for the new
item `[1, nil, 3, 4, 5]`, and then adding the item in the space we
added. But this still requires us to shift many elements down by one.
Binary Search Trees, however, can operate on sorted data much more
efficiently.
A binary search tree consists of a series of connected nodes. Each node
contains a piece of data (e.g. the number 3), a variable named `left`,
and a variable named `right`. The `left` and `right` variables point at
`nil`, or other nodes. Since these other nodes in turn have other nodes
beneath them, we say that the left and right variables are pointing at
subtrees. All data in the left subtree is less than or equal to the
current node's data, and all data in the right subtree is greater than
the current node's data.
For example, if we had a node containing the data 4, and we added the
data 2, our tree would look like this:
4
/
2
If we then added 6, it would look like this:
4
/ \
2 6
If we then added 3, it would look like this
4
/ \
2 6
\
3
And if we then added 1, 5, and 7, it would look like this
4
/ \
/ \
2 6
/ \ / \
1 3 5 7
## Source
### Created by
- @zilkey
### Contributed to by
- @alebaffa
- @bitfield
- @ekingery
- @ferhatelmas
- @hilary
- @jcbwlkr
- @kytrinyx
- @leenipper
- @petertseng
- @robphoenix
- @sebito91
- @sjakobi
- @tapank
- @tleen
### Based on
Josh Cheek - https://twitter.com/josh_cheek

View file

@ -0,0 +1,54 @@
// This is a "stub" file. It's a little start on your solution.
// It's not a complete solution though; you have to write some code.
// Package binarysearchtree should have a package comment that summarizes what it's about.
// https://golang.org/doc/effective_go.html#commentary
package binarysearchtree
type SearchTreeData struct {
left *SearchTreeData
data int
right *SearchTreeData
}
// NewBst creates and returns a new SearchTreeData.
func NewBst(i int) SearchTreeData {
// Write some code here to pass the test suite.
// Then remove all the stock comments.
// They're here to help you get started but they only clutter a finished solution.
// If you leave them in, reviewers may protest!
return SearchTreeData{}
}
// Insert inserts an int into the SearchTreeData.
// Inserts happen based on the rules of a BinarySearchTree
func (std *SearchTreeData) Insert(i int) {
// Write some code here to pass the test suite.
// Then remove all the stock comments.
// They're here to help you get started but they only clutter a finished solution.
// If you leave them in, reviewers may protest!
}
// MapString returns the ordered contents of SearchTreeData as a []string.
// The values are in increasing order starting with the lowest int value.
// SearchTreeData that has the numbers [1,3,7,5] added will return the
// []string ["1", "3", "5", "7"].
func (std *SearchTreeData) MapString(func(int) string) (result []string) {
// Write some code here to pass the test suite.
// Then remove all the stock comments.
// They're here to help you get started but they only clutter a finished solution.
// If you leave them in, reviewers may protest!
return []string{}
}
// MapInt returns the ordered contents of SearchTreeData as an []int.
// The values are in increasing order starting with the lowest int value.
// SearchTreeData that has the numbers [1,3,7,5] added will return the
// []int [1,3,5,7].
func (std *SearchTreeData) MapInt(func(int) int) (result []int) {
// Write some code here to pass the test suite.
// Then remove all the stock comments.
// They're here to help you get started but they only clutter a finished solution.
// If you leave them in, reviewers may protest!
return []int{}
}

View file

@ -0,0 +1,226 @@
// API:
//
// type SearchTreeData struct {
// left *SearchTreeData
// data int
// right *SearchTreeData
// }
//
// func NewBst(int) *SearchTreeData
// func (*SearchTreeData) Insert(int)
// func (*SearchTreeData) MapString(func(int) string) []string
// func (*SearchTreeData) MapInt(func(int) int) []int
package binarysearchtree
import (
"reflect"
"strconv"
"testing"
)
func TestDataIsRetained(t *testing.T) {
actual := NewBst(4).data
expected := 4
if actual != expected {
t.Errorf("NewBst(4).data: %d, want %d.", actual, expected)
}
}
func TestInsertingLess(t *testing.T) {
bst := SearchTreeData{data: 4}
bst.Insert(2)
actual := bst.data
expected := 4
if actual != expected {
t.Errorf("bst.data: %d, want %d.", actual, expected)
}
expected = 2
if bst.left == nil {
t.Fatalf("bst.left: nil, want %d.", expected)
}
actual = bst.left.data
if actual != expected {
t.Errorf("bst.left.data: %d, want %d.", actual, expected)
}
}
func TestInsertingSame(t *testing.T) {
bst := SearchTreeData{data: 4}
bst.Insert(4)
actual := bst.data
expected := 4
if actual != expected {
t.Errorf("bst.data: %d, want %d.", actual, expected)
}
expected = 4
if bst.left == nil {
t.Fatalf("bst.left: nil, want %d.", expected)
}
actual = bst.left.data
if actual != expected {
t.Errorf("bst.left.data: %d, want %d.", actual, expected)
}
}
func TestInsertingMore(t *testing.T) {
bst := SearchTreeData{data: 4}
bst.Insert(5)
actual := bst.data
expected := 4
if actual != expected {
t.Errorf("bst.data: %d, want %d.", actual, expected)
}
expected = 5
if bst.right == nil {
t.Fatalf("bst.right: nil, want %d.", expected)
}
actual = bst.right.data
if actual != expected {
t.Errorf("bst.data: %d, want %d.", actual, expected)
}
}
func TestComplexTree(t *testing.T) {
bst := SearchTreeData{data: 4}
bst.Insert(2)
bst.Insert(6)
bst.Insert(1)
bst.Insert(3)
bst.Insert(7)
bst.Insert(5)
actual := bst.data
expected := 4
if actual != expected {
t.Errorf("bst.data: %d, want %d.", actual, expected)
}
expected = 2
if bst.left == nil {
t.Fatalf("bst.left: nil, want %d.", expected)
}
actual = bst.left.data
if actual != expected {
t.Errorf("bst.left.data: %d, want %d.", actual, expected)
}
expected = 1
if bst.left.left == nil {
t.Fatalf("bst.left.left: nil, want %d.", expected)
}
actual = bst.left.left.data
if actual != expected {
t.Errorf("bst.left.left.data: %d, want %d.", actual, expected)
}
expected = 3
if bst.left.right == nil {
t.Fatalf("bst.left.right: nil, want %d.", expected)
}
actual = bst.left.right.data
if actual != expected {
t.Errorf("bst.left.right.data: %d, want %d.", actual, expected)
}
expected = 6
if bst.right == nil {
t.Fatalf("bst.right: nil, want %d.", expected)
}
actual = bst.right.data
if actual != expected {
t.Errorf("bst.right.data: %d, want %d", actual, expected)
}
expected = 5
if bst.right.left == nil {
t.Fatalf("bst.right.left: nil, want %d.", expected)
}
actual = bst.right.left.data
if actual != expected {
t.Errorf("bst.right.left.data: %d, want %d", actual, expected)
}
expected = 7
if bst.right.right == nil {
t.Fatalf("bst.right.right: nil, want %d.", expected)
}
actual = bst.right.right.data
if actual != expected {
t.Errorf("bst.right.right.data: %d, want %d", actual, expected)
}
}
func TestMapStringWithOneElement(t *testing.T) {
bst := SearchTreeData{data: 4}
actual := bst.MapString(strconv.Itoa)
expected := []string{"4"}
if !reflect.DeepEqual(actual, expected) {
t.Errorf("bst.MapString(): %q, want %q.", actual, expected)
}
}
func TestMapStringWithSmallElement(t *testing.T) {
bst := SearchTreeData{data: 4}
bst.Insert(2)
actual := bst.MapString(strconv.Itoa)
expected := []string{"2", "4"}
if !reflect.DeepEqual(actual, expected) {
t.Errorf("bst.MapString(): %q, want %q.", actual, expected)
}
}
func TestMapStringWithLargeElement(t *testing.T) {
bst := SearchTreeData{data: 4}
bst.Insert(5)
actual := bst.MapString(strconv.Itoa)
expected := []string{"4", "5"}
if !reflect.DeepEqual(actual, expected) {
t.Errorf("bst.MapString(): %q, want %q.", actual, expected)
}
}
func TestMapStringWithComplexStructure(t *testing.T) {
bst := SearchTreeData{data: 4}
bst.Insert(2)
bst.Insert(1)
bst.Insert(3)
bst.Insert(6)
bst.Insert(7)
bst.Insert(5)
actual := bst.MapString(strconv.Itoa)
expected := []string{"1", "2", "3", "4", "5", "6", "7"}
if !reflect.DeepEqual(actual, expected) {
t.Errorf("bst.MapString(): %q, want %q.", actual, expected)
}
}
func TestMapIntWithComplexStructure(t *testing.T) {
bst := SearchTreeData{data: 4}
bst.Insert(2)
bst.Insert(1)
bst.Insert(3)
bst.Insert(6)
bst.Insert(7)
bst.Insert(5)
f := func(i int) int {
return i
}
actual := bst.MapInt(f)
expected := []int{1, 2, 3, 4, 5, 6, 7}
if !reflect.DeepEqual(actual, expected) {
t.Errorf("bst.MapInt(): %v, want %v.", actual, expected)
}
}

View file

@ -0,0 +1,3 @@
module binarysearchtree
go 1.16

View file

@ -0,0 +1,35 @@
{
"blurb": "Implement a binary search algorithm.",
"authors": [],
"contributors": [
"alebaffa",
"bitfield",
"da-edra",
"ekingery",
"ferhatelmas",
"hilary",
"ilmanzo",
"kytrinyx",
"leenipper",
"petertseng",
"robphoenix",
"sebito91",
"tleen"
],
"files": {
"solution": [
"binary_search.go"
],
"test": [
"binary_search_test.go"
],
"example": [
".meta/example.go"
],
"editor": [
"cases_test.go"
]
},
"source": "Wikipedia",
"source_url": "http://en.wikipedia.org/wiki/Binary_search_algorithm"
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"binary-search","id":"447c79640e994a07b5ea1461b2672ce2","url":"https://exercism.org/tracks/go/exercises/binary-search","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
binary-search/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit binary_search.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

62
binary-search/README.md Normal file
View file

@ -0,0 +1,62 @@
# Binary Search
Welcome to Binary Search on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Implement a binary search algorithm.
Searching a sorted collection is a common task. A dictionary is a sorted
list of word definitions. Given a word, one can find its definition. A
telephone book is a sorted list of people's names, addresses, and
telephone numbers. Knowing someone's name allows one to quickly find
their telephone number and address.
If the list to be searched contains more than a few items (a dozen, say)
a binary search will require far fewer comparisons than a linear search,
but it imposes the requirement that the list be sorted.
In computer science, a binary search or half-interval search algorithm
finds the position of a specified input value (the search "key") within
an array sorted by key value.
In each step, the algorithm compares the search key value with the key
value of the middle element of the array.
If the keys match, then a matching element has been found and its index,
or position, is returned.
Otherwise, if the search key is less than the middle element's key, then
the algorithm repeats its action on the sub-array to the left of the
middle element or, if the search key is greater, on the sub-array to the
right.
If the remaining array to be searched is empty, then the key cannot be
found in the array and a special "not found" indication is returned.
A binary search halves the number of items to check with each iteration,
so locating an item (or determining its absence) takes logarithmic time.
A binary search is a dichotomic divide and conquer search algorithm.
## Source
### Contributed to by
- @alebaffa
- @bitfield
- @da-edra
- @ekingery
- @ferhatelmas
- @hilary
- @ilmanzo
- @kytrinyx
- @leenipper
- @petertseng
- @robphoenix
- @sebito91
- @tleen
### Based on
Wikipedia - http://en.wikipedia.org/wiki/Binary_search_algorithm

View file

@ -0,0 +1,5 @@
package binarysearch
func SearchInts(list []int, key int) int {
panic("Please implement the SearchInts function")
}

View file

@ -0,0 +1,55 @@
package binarysearch
import (
"fmt"
"math/rand"
"testing"
)
func TestSearchInts(t *testing.T) {
for _, test := range testCases {
if x := SearchInts(test.slice, test.key); x != test.x {
t.Fatalf("FAIL: %s\nSearchInts(%#v, %d) = %d, want %d",
test.description, test.slice, test.key, x, test.x)
}
t.Logf("SUCCESS: %s", test.description)
}
}
// Benchmarks also test searching larger random slices
type query struct {
slice []int
x int
}
func newQuery(n int) (query, error) {
q := query{slice: make([]int, n)}
for i := 0; i < n; i++ {
q.slice[i] = i
}
q.x = rand.Intn(n)
if res := SearchInts(q.slice, q.x); res != q.x {
return q, fmt.Errorf("Search of %d values gave different answer", n)
}
return q, nil
}
func runBenchmark(n int, b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
q, err := newQuery(n)
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
SearchInts(q.slice, q.x)
}
}
func Benchmark1e2(b *testing.B) { runBenchmark(1e2, b) }
func Benchmark1e4(b *testing.B) { runBenchmark(1e4, b) }
func Benchmark1e6(b *testing.B) { runBenchmark(1e6, b) }
func Benchmark1e8(b *testing.B) { runBenchmark(1e8, b) }

View file

@ -0,0 +1,91 @@
package binarysearch
// Source: exercism/problem-specifications
// Commit: bfb218f binary-search: test description tweak
// Problem Specifications Version: 1.3.0
var testCases = []struct {
description string
slice []int
key int
x int
err string
}{
{
description: "finds a value in an array with one element",
slice: []int{6},
key: 6,
x: 0,
err: "",
},
{
description: "finds a value in the middle of an array",
slice: []int{1, 3, 4, 6, 8, 9, 11},
key: 6,
x: 3,
err: "",
},
{
description: "finds a value at the beginning of an array",
slice: []int{1, 3, 4, 6, 8, 9, 11},
key: 1,
x: 0,
err: "",
},
{
description: "finds a value at the end of an array",
slice: []int{1, 3, 4, 6, 8, 9, 11},
key: 11,
x: 6,
err: "",
},
{
description: "finds a value in an array of odd length",
slice: []int{1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 634},
key: 144,
x: 9,
err: "",
},
{
description: "finds a value in an array of even length",
slice: []int{1, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377},
key: 21,
x: 5,
err: "",
},
{
description: "identifies that a value is not included in the array",
slice: []int{1, 3, 4, 6, 8, 9, 11},
key: 7,
x: -1,
err: "value not in array",
},
{
description: "a value smaller than the array's smallest value is not found",
slice: []int{1, 3, 4, 6, 8, 9, 11},
key: 0,
x: -1,
err: "value not in array",
},
{
description: "a value larger than the array's largest value is not found",
slice: []int{1, 3, 4, 6, 8, 9, 11},
key: 13,
x: -1,
err: "value not in array",
},
{
description: "nothing is found in an empty array",
slice: []int{},
key: 1,
x: -1,
err: "value not in array",
},
{
description: "nothing is found when the left and right bounds cross",
slice: []int{1, 2},
key: 0,
x: -1,
err: "value not in array",
},
}

3
binary-search/go.mod Normal file
View file

@ -0,0 +1,3 @@
module binarysearch
go 1.16

40
bob/.exercism/config.json Normal file
View file

@ -0,0 +1,40 @@
{
"blurb": "Bob is a lackadaisical teenager. In conversation, his responses are very limited.",
"authors": [
"kytrinyx"
],
"contributors": [
"alebaffa",
"austinlyons",
"bitfield",
"ekingery",
"ferhatelmas",
"hilary",
"leenipper",
"levicook",
"petertseng",
"robphoenix",
"sebito91",
"soniakeys",
"strangeman",
"tleen",
"tompao",
"Tonkpils"
],
"files": {
"solution": [
"bob.go"
],
"test": [
"bob_test.go"
],
"example": [
".meta/example.go"
],
"editor": [
"cases_test.go"
]
},
"source": "Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial.",
"source_url": "http://pine.fm/LearnToProgram/?Chapter=06"
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"bob","id":"194f002cb95349529fea94519879a3cb","url":"https://exercism.org/tracks/go/exercises/bob","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
bob/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit bob.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

50
bob/README.md Normal file
View file

@ -0,0 +1,50 @@
# Bob
Welcome to Bob on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Bob is a lackadaisical teenager. In conversation, his responses are very limited.
Bob answers 'Sure.' if you ask him a question, such as "How are you?".
He answers 'Whoa, chill out!' if you YELL AT HIM (in all capitals).
He answers 'Calm down, I know what I'm doing!' if you yell a question at him.
He says 'Fine. Be that way!' if you address him without actually saying
anything.
He answers 'Whatever.' to anything else.
Bob's conversational partner is a purist when it comes to written communication and always follows normal rules regarding sentence punctuation in English.
## Source
### Created by
- @kytrinyx
### Contributed to by
- @alebaffa
- @austinlyons
- @bitfield
- @ekingery
- @ferhatelmas
- @hilary
- @leenipper
- @levicook
- @petertseng
- @robphoenix
- @sebito91
- @soniakeys
- @strangeman
- @tleen
- @tompao
- @Tonkpils
### Based on
Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. - http://pine.fm/LearnToProgram/?Chapter=06

15
bob/bob.go Normal file
View file

@ -0,0 +1,15 @@
// This is a "stub" file. It's a little start on your solution.
// It's not a complete solution though; you have to write some code.
// Package bob should have a package comment that summarizes what it's about.
// https://golang.org/doc/effective_go.html#commentary
package bob
// Hey should have a comment documenting it.
func Hey(remark string) string {
// Write some code here to pass the test suite.
// Then remove all the stock comments.
// They're here to help you get started but they only clutter a finished solution.
// If you leave them in, reviewers may protest!
return ""
}

28
bob/bob_test.go Normal file
View file

@ -0,0 +1,28 @@
package bob
import "testing"
func TestHey(t *testing.T) {
for _, tt := range testCases {
actual := Hey(tt.input)
if actual != tt.expected {
msg := `
ALICE (%s): %q
BOB: %s
Expected Bob to respond: %s`
t.Fatalf(msg, tt.description, tt.input, actual, tt.expected)
}
}
}
func BenchmarkHey(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
for i := 0; i < b.N; i++ {
for _, tt := range testCases {
Hey(tt.input)
}
}
}

137
bob/cases_test.go Normal file
View file

@ -0,0 +1,137 @@
package bob
// Source: exercism/problem-specifications
// Commit: 1904e91 Bob: Cleans up language on a couple of test cases
// Problem Specifications Version: 1.5.0
var testCases = []struct {
description string
input string
expected string
}{
{
"stating something",
"Tom-ay-to, tom-aaaah-to.",
"Whatever.",
},
{
"shouting",
"WATCH OUT!",
"Whoa, chill out!",
},
{
"shouting gibberish",
"FCECDFCAAB",
"Whoa, chill out!",
},
{
"asking a question",
"Does this cryogenic chamber make me look fat?",
"Sure.",
},
{
"asking a numeric question",
"You are, what, like 15?",
"Sure.",
},
{
"asking gibberish",
"fffbbcbeab?",
"Sure.",
},
{
"talking forcefully",
"Hi there!",
"Whatever.",
},
{
"using acronyms in regular speech",
"It's OK if you don't want to go to the DMV.",
"Whatever.",
},
{
"forceful question",
"WHAT'S GOING ON?",
"Calm down, I know what I'm doing!",
},
{
"shouting numbers",
"1, 2, 3 GO!",
"Whoa, chill out!",
},
{
"no letters",
"1, 2, 3",
"Whatever.",
},
{
"question with no letters",
"4?",
"Sure.",
},
{
"shouting with special characters",
"ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!",
"Whoa, chill out!",
},
{
"shouting with no exclamation mark",
"I HATE THE DMV",
"Whoa, chill out!",
},
{
"statement containing question mark",
"Ending with ? means a question.",
"Whatever.",
},
{
"non-letters with question",
":) ?",
"Sure.",
},
{
"prattling on",
"Wait! Hang on. Are you going to be OK?",
"Sure.",
},
{
"silence",
"",
"Fine. Be that way!",
},
{
"prolonged silence",
" ",
"Fine. Be that way!",
},
{
"alternate silence",
"\t\t\t\t\t\t\t\t\t\t",
"Fine. Be that way!",
},
{
"multiple line question",
"\nDoes this cryogenic chamber make me look fat?\nNo.",
"Whatever.",
},
{
"starting with whitespace",
" hmmmmmmm...",
"Whatever.",
},
{
"ending with whitespace",
"Okay if like my spacebar quite a bit? ",
"Sure.",
},
{
"other whitespace",
"\n\r \t",
"Fine. Be that way!",
},
{
"non-question ending with whitespace",
"This is a statement ending with whitespace ",
"Whatever.",
},
}

3
bob/go.mod Normal file
View file

@ -0,0 +1,3 @@
module bob
go 1.16

View file

@ -0,0 +1,22 @@
{
"authors": [
"PakkuDon"
],
"files": {
"solution": [
"bottle_song.go"
],
"test": [
"bottle_song_test.go"
],
"example": [
".meta/example.go"
],
"invalidator": [
"go.mod"
]
},
"blurb": "Produce the lyrics to the popular children's repetitive song: Ten Green Bottles.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Ten_Green_Bottles"
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"bottle-song","id":"6f3ee5c29c9449c48f06d291e3d23ce4","url":"https://exercism.org/tracks/go/exercises/bottle-song","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
bottle-song/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit bottle_song.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

72
bottle-song/README.md Normal file
View file

@ -0,0 +1,72 @@
# Bottle Song
Welcome to Bottle Song on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Recite the lyrics to that popular children's repetitive song: Ten Green Bottles.
Note that not all verses are identical.
```text
Ten green bottles hanging on the wall,
Ten green bottles hanging on the wall,
And if one green bottle should accidentally fall,
There'll be nine green bottles hanging on the wall.
Nine green bottles hanging on the wall,
Nine green bottles hanging on the wall,
And if one green bottle should accidentally fall,
There'll be eight green bottles hanging on the wall.
Eight green bottles hanging on the wall,
Eight green bottles hanging on the wall,
And if one green bottle should accidentally fall,
There'll be seven green bottles hanging on the wall.
Seven green bottles hanging on the wall,
Seven green bottles hanging on the wall,
And if one green bottle should accidentally fall,
There'll be six green bottles hanging on the wall.
Six green bottles hanging on the wall,
Six green bottles hanging on the wall,
And if one green bottle should accidentally fall,
There'll be five green bottles hanging on the wall.
Five green bottles hanging on the wall,
Five green bottles hanging on the wall,
And if one green bottle should accidentally fall,
There'll be four green bottles hanging on the wall.
Four green bottles hanging on the wall,
Four green bottles hanging on the wall,
And if one green bottle should accidentally fall,
There'll be three green bottles hanging on the wall.
Three green bottles hanging on the wall,
Three green bottles hanging on the wall,
And if one green bottle should accidentally fall,
There'll be two green bottles hanging on the wall.
Two green bottles hanging on the wall,
Two green bottles hanging on the wall,
And if one green bottle should accidentally fall,
There'll be one green bottle hanging on the wall.
One green bottle hanging on the wall,
One green bottle hanging on the wall,
And if one green bottle should accidentally fall,
There'll be no green bottles hanging on the wall.
```
## Source
### Created by
- @PakkuDon
### Based on
Wikipedia - https://en.wikipedia.org/wiki/Ten_Green_Bottles

View file

@ -0,0 +1,5 @@
package bottlesong
func Recite(startBottles, takeDown int) []string {
panic("Please implement the Recite function")
}

View file

@ -0,0 +1,78 @@
package bottlesong
import (
"fmt"
"strings"
"testing"
"unicode"
)
func TestRecite(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
actual := Recite(tc.input.startBottles, tc.input.takeDown)
if !equal(actual, tc.expected) {
t.Errorf("Recite(%d, %d) = %q, want: %q", tc.input.startBottles, tc.input.takeDown, actual, tc.expected)
}
})
}
}
func equal(a, b []string) bool {
if len(b) != len(a) {
return false
}
if len(a) == 0 && len(b) == 0 {
return true
}
return fmt.Sprintf("%v", a) == fmt.Sprintf("%v", b)
}
// Title is a copy of strings.Title function of the stdlib.
// The copy is here because strings.Title is deprecated but we still
// want to use this function as the alternative would require us to support
// external dependencies which we don't yet (tracking issue https://github.com/exercism/go/issues/2379).
// Students should still be able to use strings.Title if they want.
// Since this exercise is currently deprecated, this shouldn't matter too much.
func Title(s string) string {
// Use a closure here to remember state.
// Hackish but effective. Depends on Map scanning in order and calling
// the closure once per rune.
prev := ' '
return strings.Map(
func(r rune) rune {
if isSeparator(prev) {
prev = r
return unicode.ToTitle(r)
}
prev = r
return r
},
s)
}
// Copy of strings.isSeparator function of the stdlib.
func isSeparator(r rune) bool {
// ASCII alphanumerics and underscore are not separators
if r <= 0x7F {
switch {
case '0' <= r && r <= '9':
return false
case 'a' <= r && r <= 'z':
return false
case 'A' <= r && r <= 'Z':
return false
case r == '_':
return false
}
return true
}
// Letters and digits are not separators
if unicode.IsLetter(r) || unicode.IsDigit(r) {
return false
}
// Otherwise, all we can do for now is treat spaces as separators.
return unicode.IsSpace(r)
}

75
bottle-song/cases_test.go Normal file
View file

@ -0,0 +1,75 @@
package bottlesong
// This is an auto-generated file. Do not change it manually. Run the generator to update the file.
// See https://github.com/exercism/go#synchronizing-tests-and-instructions
// Source: exercism/problem-specifications
// Commit: 472204b bottle-song: Reimplement test cases checking for "One green bottles" (#2102)
type bottleSongInput struct {
startBottles int
takeDown int
}
var testCases = []struct {
description string
input bottleSongInput
expected []string
}{
{
description: "first generic verse",
input: bottleSongInput{
startBottles: 10,
takeDown: 1,
},
expected: []string{"Ten green bottles hanging on the wall,", "Ten green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be nine green bottles hanging on the wall."},
},
{
description: "last generic verse",
input: bottleSongInput{
startBottles: 3,
takeDown: 1,
},
expected: []string{"Three green bottles hanging on the wall,", "Three green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be two green bottles hanging on the wall."},
},
{
description: "verse with 2 bottles",
input: bottleSongInput{
startBottles: 2,
takeDown: 1,
},
expected: []string{"Two green bottles hanging on the wall,", "Two green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be one green bottle hanging on the wall."},
},
{
description: "verse with 1 bottle",
input: bottleSongInput{
startBottles: 1,
takeDown: 1,
},
expected: []string{"One green bottle hanging on the wall,", "One green bottle hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be no green bottles hanging on the wall."},
},
{
description: "first two verses",
input: bottleSongInput{
startBottles: 10,
takeDown: 2,
},
expected: []string{"Ten green bottles hanging on the wall,", "Ten green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be nine green bottles hanging on the wall.", "", "Nine green bottles hanging on the wall,", "Nine green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be eight green bottles hanging on the wall."},
},
{
description: "last three verses",
input: bottleSongInput{
startBottles: 3,
takeDown: 3,
},
expected: []string{"Three green bottles hanging on the wall,", "Three green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be two green bottles hanging on the wall.", "", "Two green bottles hanging on the wall,", "Two green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be one green bottle hanging on the wall.", "", "One green bottle hanging on the wall,", "One green bottle hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be no green bottles hanging on the wall."},
},
{
description: "all verses",
input: bottleSongInput{
startBottles: 10,
takeDown: 10,
},
expected: []string{"Ten green bottles hanging on the wall,", "Ten green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be nine green bottles hanging on the wall.", "", "Nine green bottles hanging on the wall,", "Nine green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be eight green bottles hanging on the wall.", "", "Eight green bottles hanging on the wall,", "Eight green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be seven green bottles hanging on the wall.", "", "Seven green bottles hanging on the wall,", "Seven green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be six green bottles hanging on the wall.", "", "Six green bottles hanging on the wall,", "Six green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be five green bottles hanging on the wall.", "", "Five green bottles hanging on the wall,", "Five green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be four green bottles hanging on the wall.", "", "Four green bottles hanging on the wall,", "Four green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be three green bottles hanging on the wall.", "", "Three green bottles hanging on the wall,", "Three green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be two green bottles hanging on the wall.", "", "Two green bottles hanging on the wall,", "Two green bottles hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be one green bottle hanging on the wall.", "", "One green bottle hanging on the wall,", "One green bottle hanging on the wall,", "And if one green bottle should accidentally fall,", "There'll be no green bottles hanging on the wall."},
},
}

3
bottle-song/go.mod Normal file
View file

@ -0,0 +1,3 @@
module bottlesong
go 1.18

View file

@ -0,0 +1,34 @@
{
"blurb": "A data structure that uses a single, fixed-size buffer as if it were connected end-to-end.",
"authors": [
"soniakeys"
],
"contributors": [
"alebaffa",
"bitfield",
"dchapes",
"ekingery",
"ferhatelmas",
"hilary",
"kytrinyx",
"leenipper",
"manavo",
"petertseng",
"robphoenix",
"sebito91",
"tleen"
],
"files": {
"solution": [
"circular_buffer.go"
],
"test": [
"circular_buffer_test.go"
],
"example": [
".meta/example.go"
]
},
"source": "Wikipedia",
"source_url": "http://en.wikipedia.org/wiki/Circular_buffer"
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"circular-buffer","id":"76c656cd7d2640dd9702cc8d798d0741","url":"https://exercism.org/tracks/go/exercises/circular-buffer","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
circular-buffer/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit circular_buffer.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

82
circular-buffer/README.md Normal file
View file

@ -0,0 +1,82 @@
# Circular Buffer
Welcome to Circular Buffer on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
A circular buffer, cyclic buffer or ring buffer is a data structure that
uses a single, fixed-size buffer as if it were connected end-to-end.
A circular buffer first starts empty and of some predefined length. For
example, this is a 7-element buffer:
<!-- prettier-ignore -->
[ ][ ][ ][ ][ ][ ][ ]
Assume that a 1 is written into the middle of the buffer (exact starting
location does not matter in a circular buffer):
<!-- prettier-ignore -->
[ ][ ][ ][1][ ][ ][ ]
Then assume that two more elements are added — 2 & 3 — which get
appended after the 1:
<!-- prettier-ignore -->
[ ][ ][ ][1][2][3][ ]
If two elements are then removed from the buffer, the oldest values
inside the buffer are removed. The two elements removed, in this case,
are 1 & 2, leaving the buffer with just a 3:
<!-- prettier-ignore -->
[ ][ ][ ][ ][ ][3][ ]
If the buffer has 7 elements then it is completely full:
<!-- prettier-ignore -->
[5][6][7][8][9][3][4]
When the buffer is full an error will be raised, alerting the client
that further writes are blocked until a slot becomes free.
When the buffer is full, the client can opt to overwrite the oldest
data with a forced write. In this case, two more elements — A & B —
are added and they overwrite the 3 & 4:
<!-- prettier-ignore -->
[5][6][7][8][9][A][B]
3 & 4 have been replaced by A & B making 5 now the oldest data in the
buffer. Finally, if two elements are removed then what would be
returned is 5 & 6 yielding the buffer:
<!-- prettier-ignore -->
[ ][ ][7][8][9][A][B]
Because there is space available, if the client again uses overwrite
to store C & D then the space where 5 & 6 were stored previously will
be used not the location of 7 & 8. 7 is still the oldest element and
the buffer is once again full.
<!-- prettier-ignore -->
[C][D][7][8][9][A][B]
## Source
### Created by
- @soniakeys
### Contributed to by
- @alebaffa
- @bitfield
- @dchapes
- @ekingery
- @ferhatelmas
- @hilary
- @kytrinyx
- @leenipper
- @manavo
- @petertseng
- @robphoenix
- @sebito91
- @tleen
### Based on
Wikipedia - http://en.wikipedia.org/wiki/Circular_buffer

View file

@ -0,0 +1,30 @@
package circular
// Implement a circular buffer of bytes supporting both overflow-checked writes
// and unconditional, possibly overwriting, writes.
//
// We chose the provided API so that Buffer implements io.ByteReader
// and io.ByteWriter and can be used (size permitting) as a drop in
// replacement for anything using that interface.
// Define the Buffer type here.
func NewBuffer(size int) *Buffer {
panic("Please implement the NewBuffer function")
}
func (b *Buffer) ReadByte() (byte, error) {
panic("Please implement the ReadByte function")
}
func (b *Buffer) WriteByte(c byte) error {
panic("Please implement the WriteByte function")
}
func (b *Buffer) Overwrite(c byte) {
panic("Please implement the Overwrite function")
}
func (b *Buffer) Reset() {
panic("Please implement the Reset function")
}

View file

@ -0,0 +1,199 @@
package circular
import (
"io"
"testing"
)
// Here is one way you can have a test case verify that the expected
// interfaces are implemented.
var _ io.ByteReader = new(Buffer)
var _ io.ByteWriter = new(Buffer)
// testBuffer and methods support the tests, providing log and fail messages.
type testBuffer struct {
*testing.T
b *Buffer
}
func nb(size int, t *testing.T) testBuffer {
t.Logf("NewBuffer(%d)", size)
return testBuffer{t, NewBuffer(size)}
}
func (tb testBuffer) read(want byte) {
switch c, err := tb.b.ReadByte(); {
case err != nil:
var _ error = err
tb.Fatalf("ReadByte() failed unexpectedly: %v", err)
case c != want:
tb.Fatalf("ReadByte() = %c, want %c.", c, want)
}
tb.Logf("ReadByte %c", want)
}
func (tb testBuffer) readFail() {
c, err := tb.b.ReadByte()
if err == nil {
tb.Fatalf("ReadByte() = %c, expected a failure", c)
}
var _ error = err
tb.Log("ReadByte() fails as expected")
}
func (tb testBuffer) write(c byte) {
if err := tb.b.WriteByte(c); err != nil {
var _ error = err
tb.Fatalf("WriteByte(%c) failed unexpectedly: %v", c, err)
}
tb.Logf("WriteByte(%c)", c)
}
func (tb testBuffer) writeFail(c byte) {
err := tb.b.WriteByte(c)
if err == nil {
tb.Fatalf("WriteByte(%c) succeeded, expected a failure", c)
}
var _ error = err
tb.Logf("WriteByte(%c) fails as expected", c)
}
func (tb testBuffer) reset() {
tb.b.Reset()
tb.Log("Reset()")
}
func (tb testBuffer) overwrite(c byte) {
tb.b.Overwrite(c)
tb.Logf("Overwrite(%c)", c)
}
// tests. separate functions so log will have descriptive test name.
func TestReadEmptyBuffer(t *testing.T) {
tb := nb(1, t)
tb.readFail()
}
func TestWriteAndReadOneItem(t *testing.T) {
tb := nb(1, t)
tb.write('1')
tb.read('1')
tb.readFail()
}
func TestWriteAndReadMultipleItems(t *testing.T) {
tb := nb(2, t)
tb.write('1')
tb.write('2')
tb.read('1')
tb.read('2')
tb.readFail()
}
func TestReset(t *testing.T) {
tb := nb(3, t)
tb.write('1')
tb.write('2')
tb.write('3')
tb.reset()
tb.write('1')
tb.write('3')
tb.read('1')
tb.write('4')
tb.read('3')
}
func TestAlternateWriteAndRead(t *testing.T) {
tb := nb(2, t)
tb.write('1')
tb.read('1')
tb.write('2')
tb.read('2')
}
func TestReadOldestItem(t *testing.T) {
tb := nb(3, t)
tb.write('1')
tb.write('2')
tb.read('1')
tb.write('3')
tb.read('2')
tb.read('3')
}
func TestWriteFullBuffer(t *testing.T) {
tb := nb(2, t)
tb.write('1')
tb.write('2')
tb.writeFail('A')
}
func TestOverwriteFull(t *testing.T) {
tb := nb(2, t)
tb.write('1')
tb.write('2')
tb.overwrite('A')
tb.read('2')
tb.read('A')
tb.readFail()
}
func TestOverwriteNonFull(t *testing.T) {
tb := nb(2, t)
tb.write('1')
tb.overwrite('2')
tb.read('1')
tb.read('2')
tb.readFail()
}
func TestAlternateReadAndOverwrite(t *testing.T) {
tb := nb(5, t)
tb.write('1')
tb.write('2')
tb.write('3')
tb.read('1')
tb.read('2')
tb.write('4')
tb.read('3')
tb.write('5')
tb.write('6')
tb.write('7')
tb.write('8')
tb.overwrite('A')
tb.overwrite('B')
tb.read('6')
tb.read('7')
tb.read('8')
tb.read('A')
tb.read('B')
tb.readFail()
}
func BenchmarkOverwrite(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
c := NewBuffer(100)
b.ResetTimer()
for i := 0; i < b.N; i++ {
c.Overwrite(0)
}
b.SetBytes(int64(b.N))
}
func BenchmarkWriteRead(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
c := NewBuffer(100)
b.ResetTimer()
for i := 0; i < b.N; i++ {
c.WriteByte(0)
c.ReadByte()
}
b.SetBytes(int64(b.N))
}

3
circular-buffer/go.mod Normal file
View file

@ -0,0 +1,3 @@
module standard
go 1.16

View file

@ -0,0 +1,41 @@
{
"blurb": "Implement a clock that handles times without dates.",
"authors": [
"soniakeys"
],
"contributors": [
"alebaffa",
"bitfield",
"cwithmichael",
"da-edra",
"dmgawel",
"ekingery",
"ferhatelmas",
"hilary",
"kytrinyx",
"leenipper",
"nywilken",
"petertseng",
"pminten",
"robphoenix",
"sebito91",
"thenickcox",
"tleen"
],
"files": {
"solution": [
"clock.go"
],
"test": [
"clock_test.go"
],
"example": [
".meta/example.go"
],
"editor": [
"cases_test.go"
]
},
"source": "Pairing session with Erin Drummond",
"source_url": "https://twitter.com/ebdrummond"
}

View file

@ -0,0 +1 @@
{"track":"go","exercise":"clock","id":"8e3ecc7d2fc64c52b15e61434cd99094","url":"https://exercism.org/tracks/go/exercises/clock","handle":"snowyforest","is_requester":true,"auto_approve":false}

41
clock/HELP.md Normal file
View file

@ -0,0 +1,41 @@
# Help
## Running the tests
To run the tests run the command `go test` from within the exercise directory.
If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
flags:
go test -v --bench . --benchmem
Keep in mind that each reviewer will run benchmarks on a different machine, with
different specs, so the results from these benchmark tests may vary.
## Submitting your solution
You can submit your solution using the `exercism submit clock.go` command.
This command will upload your solution to the Exercism website and print the solution page's URL.
It's possible to submit an incomplete solution which allows you to:
- See how others have completed the exercise
- Request help from a mentor
## Need to get help?
If you'd like help solving the exercise, check the following pages:
- The [Go track's documentation](https://exercism.org/docs/tracks/go)
- The [Go track's programming category on the forum](https://forum.exercism.org/c/programming/go)
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
To get help if you're having trouble, you can use one of the following resources:
- [How to Write Go Code](https://golang.org/doc/code.html)
- [Effective Go](https://golang.org/doc/effective_go.html)
- [Go Resources](http://golang.org/help)
- [StackOverflow](http://stackoverflow.com/questions/tagged/go)

58
clock/README.md Normal file
View file

@ -0,0 +1,58 @@
# Clock
Welcome to Clock on Exercism's Go Track.
If you need help running the tests or submitting your code, check out `HELP.md`.
## Instructions
Implement a clock that handles times without dates.
You should be able to add and subtract minutes to it.
Two clocks that represent the same time should be equal to each other.
## Implementation Notes
To satisfy the requirement in the instructions about clocks being equal, values of
your Clock type need to work with the == operator. This means that if your
New function returns a pointer rather than a value, your clocks will
probably not work with ==.
While the time.Time type in the standard library (https://golang.org/pkg/time/#Time)
doesn't necessarily need to be used as a basis for your Clock type, it might
help to look at how constructors there (Date and Now) return values rather
than pointers. Note also how most time.Time methods have value receivers
rather than pointer receivers.
For some useful guidelines on when to use a value receiver or a pointer
receiver see: https://github.com/golang/go/wiki/CodeReviewComments#receiver-type
## Source
### Created by
- @soniakeys
### Contributed to by
- @alebaffa
- @bitfield
- @cwithmichael
- @da-edra
- @dmgawel
- @ekingery
- @ferhatelmas
- @hilary
- @kytrinyx
- @leenipper
- @nywilken
- @petertseng
- @pminten
- @robphoenix
- @sebito91
- @thenickcox
- @tleen
### Based on
Pairing session with Erin Drummond - https://twitter.com/ebdrummond

167
clock/cases_test.go Normal file
View file

@ -0,0 +1,167 @@
package clock
// Source: exercism/problem-specifications
// Commit: b344762 clock: Add test case for exactly negative sixty minutes.
// Problem Specifications Version: 2.4.0
// Create a new clock with an initial time
var timeTests = []struct {
h, m int
want string
}{
{8, 0, "08:00"}, // on the hour
{11, 9, "11:09"}, // past the hour
{24, 0, "00:00"}, // midnight is zero hours
{25, 0, "01:00"}, // hour rolls over
{100, 0, "04:00"}, // hour rolls over continuously
{1, 60, "02:00"}, // sixty minutes is next hour
{0, 160, "02:40"}, // minutes roll over
{0, 1723, "04:43"}, // minutes roll over continuously
{25, 160, "03:40"}, // hour and minutes roll over
{201, 3001, "11:01"}, // hour and minutes roll over continuously
{72, 8640, "00:00"}, // hour and minutes roll over to exactly midnight
{-1, 15, "23:15"}, // negative hour
{-25, 0, "23:00"}, // negative hour rolls over
{-91, 0, "05:00"}, // negative hour rolls over continuously
{1, -40, "00:20"}, // negative minutes
{1, -160, "22:20"}, // negative minutes roll over
{1, -4820, "16:40"}, // negative minutes roll over continuously
{2, -60, "01:00"}, // negative sixty minutes is previous hour
{-25, -160, "20:20"}, // negative hour and minutes both roll over
{-121, -5810, "22:10"}, // negative hour and minutes both roll over continuously
}
// Add minutes
var addTests = []struct {
h, m, a int
want string
}{
{10, 0, 3, "10:03"}, // add minutes
{6, 41, 0, "06:41"}, // add no minutes
{0, 45, 40, "01:25"}, // add to next hour
{10, 0, 61, "11:01"}, // add more than one hour
{0, 45, 160, "03:25"}, // add more than two hours with carry
{23, 59, 2, "00:01"}, // add across midnight
{5, 32, 1500, "06:32"}, // add more than one day (1500 min = 25 hrs)
{1, 1, 3500, "11:21"}, // add more than two days
}
// Subtract minutes
var subtractTests = []struct {
h, m, a int
want string
}{
{10, 3, 3, "10:00"}, // subtract minutes
{10, 3, 30, "09:33"}, // subtract to previous hour
{10, 3, 70, "08:53"}, // subtract more than an hour
{0, 3, 4, "23:59"}, // subtract across midnight
{0, 0, 160, "21:20"}, // subtract more than two hours
{6, 15, 160, "03:35"}, // subtract more than two hours with borrow
{5, 32, 1500, "04:32"}, // subtract more than one day (1500 min = 25 hrs)
{2, 20, 3000, "00:20"}, // subtract more than two days
}
// Compare two clocks for equality
type hm struct{ h, m int }
var eqTests = []struct {
c1, c2 hm
want bool
}{
// clocks with same time
{
hm{15, 37},
hm{15, 37},
true,
},
// clocks a minute apart
{
hm{15, 36},
hm{15, 37},
false,
},
// clocks an hour apart
{
hm{14, 37},
hm{15, 37},
false,
},
// clocks with hour overflow
{
hm{10, 37},
hm{34, 37},
true,
},
// clocks with hour overflow by several days
{
hm{3, 11},
hm{99, 11},
true,
},
// clocks with negative hour
{
hm{22, 40},
hm{-2, 40},
true,
},
// clocks with negative hour that wraps
{
hm{17, 3},
hm{-31, 3},
true,
},
// clocks with negative hour that wraps multiple times
{
hm{13, 49},
hm{-83, 49},
true,
},
// clocks with minute overflow
{
hm{0, 1},
hm{0, 1441},
true,
},
// clocks with minute overflow by several days
{
hm{2, 2},
hm{2, 4322},
true,
},
// clocks with negative minute
{
hm{2, 40},
hm{3, -20},
true,
},
// clocks with negative minute that wraps
{
hm{4, 10},
hm{5, -1490},
true,
},
// clocks with negative minute that wraps multiple times
{
hm{6, 15},
hm{6, -4305},
true,
},
// clocks with negative hours and minutes
{
hm{7, 32},
hm{-12, -268},
true,
},
// clocks with negative hours and minutes that wrap
{
hm{18, 7},
hm{-54, -11513},
true,
},
// full clock and zeroed clock
{
hm{24, 0},
hm{0, 0},
true,
},
}

19
clock/clock.go Normal file
View file

@ -0,0 +1,19 @@
package clock
// Define the Clock type here.
func New(h, m int) Clock {
panic("Please implement the New function")
}
func (c Clock) Add(m int) Clock {
panic("Please implement the Add function")
}
func (c Clock) Subtract(m int) Clock {
panic("Please implement the Subtract function")
}
func (c Clock) String() string {
panic("Please implement the String function")
}

146
clock/clock_test.go Normal file
View file

@ -0,0 +1,146 @@
package clock
import (
"reflect"
"strconv"
"strings"
"testing"
)
func TestCreateClock(t *testing.T) {
for _, n := range timeTests {
if got := New(n.h, n.m); got.String() != n.want {
t.Fatalf("New(%d, %d) = %q, want %q", n.h, n.m, got, n.want)
}
}
t.Log(len(timeTests), "test cases")
}
func TestAddMinutes(t *testing.T) {
for _, a := range addTests {
if got := New(a.h, a.m).Add(a.a); got.String() != a.want {
t.Fatalf("New(%d, %d).Add(%d) = %q, want %q",
a.h, a.m, a.a, got, a.want)
}
}
t.Log(len(addTests), "test cases")
}
func TestSubtractMinutes(t *testing.T) {
for _, a := range subtractTests {
if got := New(a.h, a.m).Subtract(a.a); got.String() != a.want {
t.Fatalf("New(%d, %d).Subtract(%d) = %q, want %q",
a.h, a.m, a.a, got, a.want)
}
}
t.Log(len(subtractTests), "test cases")
}
func TestAddMinutesStringless(t *testing.T) {
for _, a := range addTests {
var wantHour, wantMin int
split := strings.SplitN(a.want, ":", 2)
if len(split) > 0 {
wantHour, _ = strconv.Atoi(split[0])
}
if len(split) > 1 {
wantMin, _ = strconv.Atoi(split[1])
}
want := New(wantHour, wantMin)
if got := New(a.h, a.m).Add(a.a); !reflect.DeepEqual(got, want) {
t.Fatalf("New(%d, %d).Add(%d) = %v, want %v",
a.h, a.m, a.a, got, want)
}
}
t.Log(len(addTests), "test cases")
}
func TestSubtractMinutesStringless(t *testing.T) {
for _, a := range subtractTests {
var wantHour, wantMin int
split := strings.SplitN(a.want, ":", 2)
if len(split) > 0 {
wantHour, _ = strconv.Atoi(split[0])
}
if len(split) > 1 {
wantMin, _ = strconv.Atoi(split[1])
}
want := New(wantHour, wantMin)
if got := New(a.h, a.m).Subtract(a.a); !reflect.DeepEqual(got, want) {
t.Fatalf("New(%d, %d).Subtract(%d) = %v, want %v",
a.h, a.m, a.a, got, want)
}
}
t.Log(len(subtractTests), "test cases")
}
func TestCompareClocks(t *testing.T) {
for _, e := range eqTests {
clock1 := New(e.c1.h, e.c1.m)
clock2 := New(e.c2.h, e.c2.m)
got := clock1 == clock2
if got != e.want {
t.Log("Clock1:", clock1)
t.Log("Clock2:", clock2)
t.Logf("Clock1 == Clock2 is %t, want %t", got, e.want)
if reflect.DeepEqual(clock1, clock2) {
t.Log("(Hint: see comments in clock_test.go.)")
}
t.FailNow()
}
}
t.Log(len(eqTests), "test cases")
}
func TestAddAndCompare(t *testing.T) {
clock1 := New(15, 45).Add(16)
clock2 := New(16, 1)
if !reflect.DeepEqual(clock1, clock2) {
t.Errorf("clock.New(15,45).Add(16) differs from clock.New(16,1)")
}
}
func TestSubtractAndCompare(t *testing.T) {
clock1 := New(16, 1).Subtract(16)
clock2 := New(15, 45)
if !reflect.DeepEqual(clock1, clock2) {
t.Errorf("clock.New(16,1).Subtract(16) differs from clock.New(15,45)")
}
}
func BenchmarkAddMinutes(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
c := New(12, 0)
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, a := range addTests {
c.Add(a.a)
}
}
}
func BenchmarkSubtractMinutes(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
c := New(12, 0)
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, a := range subtractTests {
c.Subtract(a.a)
}
}
}
func BenchmarkCreateClocks(b *testing.B) {
if testing.Short() {
b.Skip("skipping benchmark in short mode.")
}
for i := 0; i < b.N; i++ {
for _, n := range timeTests {
New(n.h, n.m)
}
}
}

Some files were not shown because too many files have changed in this diff Show more