Initial upload
This commit is contained in:
22
go/chessboard/.exercism/config.json
Normal file
22
go/chessboard/.exercism/config.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"blurb": "Learn about iterating ranges by generating a chessboard.",
|
||||
"authors": [
|
||||
"brugnara",
|
||||
"tehsphinx"
|
||||
],
|
||||
"contributors": [],
|
||||
"forked_from": [
|
||||
"elixir/chessboard"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"chessboard.go"
|
||||
],
|
||||
"test": [
|
||||
"chessboard_test.go"
|
||||
],
|
||||
"exemplar": [
|
||||
".meta/exemplar.go"
|
||||
]
|
||||
}
|
||||
}
|
1
go/chessboard/.exercism/metadata.json
Normal file
1
go/chessboard/.exercism/metadata.json
Normal file
@@ -0,0 +1 @@
|
||||
{"track":"go","exercise":"chessboard","id":"72b4b3b0b72f42d8b27bc4cfa8f18090","url":"https://exercism.org/tracks/go/exercises/chessboard","handle":"halfdan","is_requester":true,"auto_approve":false}
|
40
go/chessboard/HELP.md
Normal file
40
go/chessboard/HELP.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# 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 chessboard.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)
|
||||
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
|
||||
- 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)
|
34
go/chessboard/HINTS.md
Normal file
34
go/chessboard/HINTS.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Hints
|
||||
|
||||
## General
|
||||
|
||||
- An [integer value][integers] can be defined as one or more consecutive digits.
|
||||
- A [map value][maps] stores key-value data
|
||||
|
||||
## 1. Given a Chessboard and a Rank, count how many squares are occupied
|
||||
|
||||
- You can iterate a [map][maps]
|
||||
- Check if the value is true. If it is increment. This is to count pieces.
|
||||
- You have to [explicitly return an integer][return] from a function.
|
||||
|
||||
## 2. Given a Chessboard and a File, count how many squares are occupied
|
||||
|
||||
- You'll first need to check the file is within range.
|
||||
- Loop over the chessboard.
|
||||
- Add one if the square is occupied.
|
||||
|
||||
## 3. Count how many squares are present in the given chessboard
|
||||
|
||||
- There are many ways to solve this.
|
||||
- This should return how many squares are configured in a chess-board.
|
||||
|
||||
## 4. Count how many squares are occupied in the given chessboard
|
||||
|
||||
- Get the CountInRank for all ranks in the chessboard.
|
||||
|
||||
[functions]: https://golang.org/ref/spec#Function_declarations
|
||||
[return]: https://golang.org/ref/spec#Return_statements
|
||||
[operators]: https://golang.org/ref/spec#Operators
|
||||
[integers]: https://golang.org/ref/spec#Integer_literals
|
||||
[calls]: https://golang.org/ref/spec#Calls
|
||||
[maps]: /tracks/go/concepts/maps
|
187
go/chessboard/README.md
Normal file
187
go/chessboard/README.md
Normal file
@@ -0,0 +1,187 @@
|
||||
# Chessboard
|
||||
|
||||
Welcome to Chessboard on Exercism's Go Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
|
||||
|
||||
## Introduction
|
||||
|
||||
In Go, you can iterate over a `slice` using `for` and an index, or you can use `range`.
|
||||
`range` also allows you to iterate over a `map`.
|
||||
|
||||
Every iteration returns two values: the index/key and a copy of the element at that index/key.
|
||||
|
||||
## Iterate over a slice
|
||||
|
||||
Easy as pie, loops over a slice, ordered as expected.
|
||||
|
||||
```go
|
||||
xi := []int{10, 20, 30}
|
||||
for i, x := range xi {
|
||||
fmt.Println(i, x)
|
||||
}
|
||||
// outputs:
|
||||
// 0, 10
|
||||
// 1, 20
|
||||
// 2, 30
|
||||
```
|
||||
|
||||
## Iterate over a map
|
||||
|
||||
Iterating over a map raises a new problem. The order is now random.
|
||||
|
||||
```go
|
||||
hash := map[int]int{9: 10, 99: 20, 999: 30}
|
||||
for k, v := range hash {
|
||||
fmt.Println(k, v)
|
||||
}
|
||||
// outputs, for example:
|
||||
// 99 20
|
||||
// 999 30
|
||||
// 9 10
|
||||
```
|
||||
|
||||
## Iteration omitting key or value
|
||||
|
||||
In Go an unused variable will raise an error at build time.
|
||||
Sometimes you only need the value, as per the first example:
|
||||
|
||||
```go
|
||||
xi := []int{10, 20, 30}
|
||||
for i, x := range xi {
|
||||
fmt.Println(x)
|
||||
}
|
||||
// Go build failed: i declared but not used
|
||||
```
|
||||
|
||||
You can replace the `i` with `_` which tells the compiler we don't use that value:
|
||||
|
||||
```go
|
||||
xi := []int{10, 20, 30}
|
||||
for _, x := range xi {
|
||||
fmt.Println(x)
|
||||
}
|
||||
// outputs:
|
||||
// 10
|
||||
// 20
|
||||
// 30
|
||||
```
|
||||
|
||||
If you want to only print the index, you can replace the `x` with `_`,
|
||||
or simply omit the declaration:
|
||||
|
||||
```go
|
||||
xi := []int{10, 20, 30}
|
||||
// for i, _ := range xi {
|
||||
for i := range xi {
|
||||
fmt.Println(i)
|
||||
}
|
||||
// outputs:
|
||||
// 0
|
||||
// 1
|
||||
// 2
|
||||
```
|
||||
|
||||
## Non-struct types
|
||||
|
||||
You've previously seen defining struct types.
|
||||
It is also possible to define non-struct types which you can use as an alias for a built-in type declaration, and you can define receiver functions on them to extend them in the same way as struct types.
|
||||
|
||||
```go
|
||||
type Name string
|
||||
func SayHello(n Name) {
|
||||
fmt.Printf("Hello %s\n", n)
|
||||
}
|
||||
n := Name("Fred")
|
||||
SayHello(n)
|
||||
// Output: Hello Fred
|
||||
```
|
||||
|
||||
You can also define non-struct types composed of arrays and maps.
|
||||
|
||||
```go
|
||||
type Names []string
|
||||
func SayHello(n Names) {
|
||||
for _, name := range n {
|
||||
fmt.Printf("Hello %s\n", name)
|
||||
}
|
||||
}
|
||||
n := Names([]string{"Fred", "Bill"})
|
||||
SayHello(n)
|
||||
// Output:
|
||||
// Hello Fred
|
||||
// Hello Bill
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
||||
As a chess enthusiast, you would like to write your own version of the game. Yes, there may be plenty of implementations of chess available online already, but yours will be unique!
|
||||
|
||||
Each square of the chessboard is identified by a letter-number pair:
|
||||
- The vertical columns of squares, called files, are numbered 1 through 8.
|
||||
- The horizontal rows of squares, called ranks, are labelled A through H.
|
||||
|
||||
```
|
||||
1 2 3 4 5 6 7 8
|
||||
A # _ # _ _ _ _ # A
|
||||
B _ _ _ _ # _ _ _ B
|
||||
C _ _ # _ _ _ _ _ C
|
||||
D _ _ _ _ _ _ _ _ D
|
||||
E _ _ _ _ _ # _ # E
|
||||
F _ _ _ _ _ _ _ _ F
|
||||
G _ _ _ # _ _ _ _ G
|
||||
H # # # # # # _ # H
|
||||
1 2 3 4 5 6 7 8
|
||||
```
|
||||
|
||||
## 1. Given a Chessboard and a Rank, count how many squares are occupied
|
||||
|
||||
Implement the `CountInRank(board Chessboard, rank string) int` function.
|
||||
It should count the total number of occupied squares by ranging over a map. Return an integer.
|
||||
Return a count of zero (`0`) if the given rank cannot be found in the map.
|
||||
|
||||
```go
|
||||
CountInRank(board, "A")
|
||||
// => 6
|
||||
```
|
||||
|
||||
## 2. Given a Chessboard and a File, count how many squares are occupied
|
||||
|
||||
Implement the `CountInFile(board Chessboard, file int) int` function.
|
||||
It should count the total number of occupied squares by ranging over the given file. Return an integer.
|
||||
Return a count of zero (`0`) if the given file is not a valid one (not between `1` and `8`, inclusive).
|
||||
|
||||
```go
|
||||
CountInFile(board, 2)
|
||||
// => 5
|
||||
```
|
||||
|
||||
## 3. Count how many squares are present in the given chessboard
|
||||
|
||||
Implement the `CountAll(board Chessboard) int` function.
|
||||
It should count how many squares are present in the chessboard and returns
|
||||
an integer. Since you don't need to check the content of the squares,
|
||||
consider using range omitting both `index` and `value`.
|
||||
|
||||
```go
|
||||
CountAll(board)
|
||||
// => 64
|
||||
```
|
||||
|
||||
## 4. Count how many squares are occupied in the given chessboard
|
||||
|
||||
Implement the `CountOccupied(board Chessboard) int` function.
|
||||
It should count how many squares are occupied in the chessboard.
|
||||
Return an integer.
|
||||
|
||||
```go
|
||||
CountOccupied(board)
|
||||
// => 15
|
||||
```
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @brugnara
|
||||
- @tehsphinx
|
55
go/chessboard/chessboard.go
Normal file
55
go/chessboard/chessboard.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package chessboard
|
||||
|
||||
// Declare a type named Rank which stores if a square is occupied by a piece - this will be a slice of bools
|
||||
// Declare a type named Chessboard contains a map of eight Ranks, accessed with values from "A" to "H"
|
||||
type Rank []bool
|
||||
type Chessboard map[string]Rank
|
||||
// CountInRank returns how many squares are occupied in the chessboard,
|
||||
// within the given rank
|
||||
func CountInRank(cb Chessboard, rank string) int {
|
||||
sum := 0
|
||||
file, ok := cb[rank]
|
||||
if !ok {
|
||||
return 0
|
||||
}
|
||||
for _, f := range file {
|
||||
if f {
|
||||
sum += 1
|
||||
}
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// CountInFile returns how many squares are occupied in the chessboard,
|
||||
// within the given file
|
||||
func CountInFile(cb Chessboard, file int) int {
|
||||
if file < 1 || file > 8 {
|
||||
return 0
|
||||
}
|
||||
sum := 0
|
||||
for _, rank := range cb {
|
||||
if rank[file-1] {
|
||||
sum += 1
|
||||
}
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// CountAll should count how many squares are present in the chessboard
|
||||
func CountAll(cb Chessboard) int {
|
||||
sum := 0
|
||||
for _, rank := range cb {
|
||||
sum += len(rank)
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
// CountOccupied returns how many squares are occupied in the chessboard
|
||||
func CountOccupied(cb Chessboard) int {
|
||||
sum := 0
|
||||
for name := range cb {
|
||||
sum += CountInRank(cb, name)
|
||||
}
|
||||
return sum
|
||||
}
|
100
go/chessboard/chessboard_test.go
Normal file
100
go/chessboard/chessboard_test.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package chessboard
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// newChessboard return a *Chessboard for tests
|
||||
//
|
||||
// 1 2 3 4 5 6 7 8
|
||||
// A # _ # _ _ _ _ # A
|
||||
// B _ _ _ _ # _ _ _ B
|
||||
// C _ _ # _ _ _ _ _ C
|
||||
// D _ _ _ _ _ _ _ _ D
|
||||
// E _ _ _ _ _ # _ # E
|
||||
// F _ _ _ _ _ _ _ _ F
|
||||
// G _ _ _ # _ _ _ _ G
|
||||
// H # # # # # # _ # H
|
||||
// 1 2 3 4 5 6 7 8
|
||||
func newChessboard() Chessboard {
|
||||
return Chessboard{
|
||||
"A": Rank{true, false, true, false, false, false, false, true},
|
||||
"B": Rank{false, false, false, false, true, false, false, false},
|
||||
"C": Rank{false, false, true, false, false, false, false, false},
|
||||
"D": Rank{false, false, false, false, false, false, false, false},
|
||||
"E": Rank{false, false, false, false, false, true, false, true},
|
||||
"F": Rank{false, false, false, false, false, false, false, false},
|
||||
"G": Rank{false, false, false, true, false, false, false, false},
|
||||
"H": Rank{true, true, true, true, true, true, false, true},
|
||||
}
|
||||
}
|
||||
|
||||
func TestCountInRank(t *testing.T) {
|
||||
cb := newChessboard()
|
||||
for _, test := range []struct {
|
||||
in string
|
||||
out int
|
||||
}{
|
||||
{"A", 3},
|
||||
{"B", 1},
|
||||
{"C", 1},
|
||||
{"D", 0},
|
||||
{"E", 2},
|
||||
{"F", 0},
|
||||
{"G", 1},
|
||||
{"H", 7},
|
||||
{"Z", 0},
|
||||
} {
|
||||
if out := CountInRank(cb, test.in); out != test.out {
|
||||
t.Errorf(
|
||||
"CountInRank(chessboard, '%v') returned %v while %v was expected\n",
|
||||
test.in,
|
||||
out,
|
||||
test.out,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCountInFile(t *testing.T) {
|
||||
cb := newChessboard()
|
||||
for _, test := range []struct {
|
||||
in int
|
||||
out int
|
||||
}{
|
||||
{1, 2},
|
||||
{2, 1},
|
||||
{3, 3},
|
||||
{4, 2},
|
||||
{5, 2},
|
||||
{6, 2},
|
||||
{7, 0},
|
||||
{8, 3},
|
||||
{100, 0},
|
||||
} {
|
||||
if out := CountInFile(cb, test.in); out != test.out {
|
||||
t.Errorf(
|
||||
"CountInFile(chessboard, %v) returned %v while %v was expected\n",
|
||||
test.in,
|
||||
out,
|
||||
test.out,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCountAll(t *testing.T) {
|
||||
cb := newChessboard()
|
||||
wanted := 64
|
||||
if out := CountAll(cb); out != wanted {
|
||||
t.Errorf("CountAll(chessboard) returned %v while %v was expected", out, wanted)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCountOccupied(t *testing.T) {
|
||||
cb := newChessboard()
|
||||
wanted := 15
|
||||
if out := CountOccupied(cb); out != wanted {
|
||||
t.Errorf("CountOccupied(chessboard) returned %v while %v was expected", out, wanted)
|
||||
}
|
||||
}
|
3
go/chessboard/go.mod
Normal file
3
go/chessboard/go.mod
Normal file
@@ -0,0 +1,3 @@
|
||||
module chessboard
|
||||
|
||||
go 1.16
|
Reference in New Issue
Block a user