From cf38d5bfd8567e7b35a3e8e04998b87e38e7af94 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Fri, 26 Aug 2016 09:41:44 +0200 Subject: Solve queens --- go/queen-attack/README.md | 44 ++++++++++++++++++++++++++++++ go/queen-attack/queen_attack.go | 38 ++++++++++++++++++++++++++ go/queen-attack/queen_attack_test.go | 53 ++++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 go/queen-attack/README.md create mode 100644 go/queen-attack/queen_attack.go create mode 100644 go/queen-attack/queen_attack_test.go (limited to 'go/queen-attack') 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) + } + } +} -- cgit v1.2.3