summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2016-08-26 09:41:44 +0200
committerDimitri Sokolyuk <demon@dim13.org>2016-08-26 09:41:44 +0200
commitcf38d5bfd8567e7b35a3e8e04998b87e38e7af94 (patch)
tree3d152ccdab56cc289a7ff3527921827312f38d4f
parent5905c68a1fbae71682ff2edea7c009ad0355e9fb (diff)
Solve queens
-rw-r--r--go/queen-attack/README.md44
-rw-r--r--go/queen-attack/queen_attack.go38
-rw-r--r--go/queen-attack/queen_attack_test.go53
3 files changed, 135 insertions, 0 deletions
diff --git a/go/queen-attack/README.md b/go/queen-attack/README.md
new file mode 100644
index 0000000..9c6a402
--- /dev/null
+++ b/go/queen-attack/README.md
@@ -0,0 +1,44 @@
+# Queen Attack
+
+Write a program that positions two queens on a chess board and indicates whether or not they are positioned so that they can attack each other.
+
+In the game of chess, a queen can attack pieces which are on the same
+row, column, or diagonal.
+
+A chessboard can be represented by an 8 by 8 array.
+
+So if you're told the white queen is at (2, 3) and the black queen at
+(5, 6), then you'd know you've got a set-up like so:
+
+```plain
+_ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ _
+_ _ _ W _ _ _ _
+_ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ _
+_ _ _ _ _ _ B _
+_ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ _
+```
+
+You'd also be able to answer whether the queens can attack each other.
+In this case, that answer would be yes, they can, because both pieces
+share a diagonal.
+
+To run the tests simply run the command `go test` in the exercise directory.
+
+If the test suite contains benchmarks, you can run these with the `-bench`
+flag:
+
+ go test -bench .
+
+For more detailed info about the Go track see the [help
+page](http://exercism.io/languages/go).
+
+## Source
+
+J Dalbey's Programming Practice problems [http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html](http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html)
+
+## Submitting Incomplete Problems
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.
+
diff --git a/go/queen-attack/queen_attack.go b/go/queen-attack/queen_attack.go
new file mode 100644
index 0000000..536ae47
--- /dev/null
+++ b/go/queen-attack/queen_attack.go
@@ -0,0 +1,38 @@
+package queenattack
+
+import "errors"
+
+func abs(n int) int {
+ if n < 0 {
+ return -n
+ }
+ return n
+}
+
+func parseLoc(l string) (int, int, error) {
+ if len(l) != 2 {
+ return 0, 0, errors.New("invalid")
+ }
+ if l[0] < 'a' || l[0] > 'h' {
+ return 0, 0, errors.New("off board")
+ }
+ if l[1] < '1' || l[1] > '8' {
+ return 0, 0, errors.New("off board")
+ }
+ return int(l[0] - 'a'), int(l[1] - '1'), nil
+}
+
+func CanQueenAttack(w, b string) (bool, error) {
+ if w == b {
+ return false, errors.New("same square")
+ }
+ wx, wy, err := parseLoc(w)
+ if err != nil {
+ return false, err
+ }
+ bx, by, err := parseLoc(b)
+ if err != nil {
+ return false, err
+ }
+ return wx == bx || wy == by || abs(wx-bx) == abs(wy-by), nil
+}
diff --git a/go/queen-attack/queen_attack_test.go b/go/queen-attack/queen_attack_test.go
new file mode 100644
index 0000000..586b060
--- /dev/null
+++ b/go/queen-attack/queen_attack_test.go
@@ -0,0 +1,53 @@
+package queenattack
+
+import "testing"
+
+// Arguments to CanQueenAttack are in algebraic notation.
+// See http://en.wikipedia.org/wiki/Algebraic_notation_(chess)
+
+var tests = []struct {
+ w, b string
+ attack bool
+ ok bool
+}{
+ {"b4", "b4", false, false}, // same square
+ {"a8", "b9", false, false}, // off board
+ {"here", "there", false, false}, // invalid
+ {"", "", false, false},
+
+ {"b3", "d7", false, true}, // no attack
+ {"b4", "b7", true, true}, // same file
+ {"e4", "b4", true, true}, // same rank
+ {"a1", "f6", true, true}, // common diagonals
+ {"a6", "b7", true, true},
+ {"d1", "f3", true, true},
+ {"f1", "a6", true, true},
+}
+
+func TestCanQueenAttack(t *testing.T) {
+ for _, test := range tests {
+ switch attack, err := CanQueenAttack(test.w, test.b); {
+ case err != nil:
+ if test.ok {
+ t.Fatalf("CanQueenAttack(%s, %s) returned error %q. "+
+ "Error not expected.",
+ test.w, test.b, err)
+ }
+ case !test.ok:
+ t.Fatalf("CanQueenAttack(%s, %s) = %t, %v. Expected error.",
+ test.w, test.b, attack, err)
+ case attack != test.attack:
+ t.Fatalf("CanQueenAttack(%s, %s) = %t, want %t.",
+ test.w, test.b, attack, test.attack)
+ }
+ }
+}
+
+// Benchmark combined time for all test cases
+func BenchmarkCanQueenAttack(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ for _, test := range tests {
+ CanQueenAttack(test.w, test.b)
+ }
+ }
+}