From 20944d31cfbc4c6c4d27c66f81c3508849a1820f Mon Sep 17 00:00:00 2001 From: jimi Date: Thu, 10 Mar 2016 14:15:12 -0600 Subject: [PATCH] Initial commit --- README.md | 44 ++++++++++++++++++++++++++++++++++ secret_handshake.go | 51 ++++++++++++++++++++++++++++++++++++++++ secret_handshake_test.go | 43 +++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 README.md create mode 100644 secret_handshake.go create mode 100644 secret_handshake_test.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..3311474 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# Secret Handshake + +Write a program that will take a decimal number, and convert it to the appropriate sequence of events for a secret handshake. + +> There are 10 types of people in the world: Those who understand +> binary, and those who don't. + +You and your fellow cohort of those in the "know" when it comes to +binary decide to come up with a secret "handshake". + +``` +1 = wink +10 = double blink +100 = close your eyes +1000 = jump + + +10000 = Reverse the order of the operations in the secret handshake. +``` + +``` +handshake = SecretHandshake.new 9 +handshake.commands # => ["wink","jump"] + +handshake = SecretHandshake.new "11001" +handshake.commands # => ["jump","wink"] +``` + +The program should consider strings specifying an invalid binary as the +value 0. + +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 + +Bert, in Mary Poppins [view source](http://www.imdb.com/character/ch0011238/quotes) diff --git a/secret_handshake.go b/secret_handshake.go new file mode 100644 index 0000000..368c6f4 --- /dev/null +++ b/secret_handshake.go @@ -0,0 +1,51 @@ +// Package secret converts an integer value into a secret phrase +package secret + +// Define friendly names for the bitmasks. +const ( + WINK int = 1 << iota // 00001 + BLINK // 00010 + CLOSE // 00100 + JUMP // 01000 + REVERSE // 10000 +) + +// Handshake receives an integer argument and returns a string slice with +// the code words in the proper sequence. +func Handshake(i int) []string { + var h []string + m := map[int]string{ + WINK: "wink", + BLINK: "double blink", + CLOSE: "close your eyes", + JUMP: "jump", + } + + // Return the original empty slice if the integer is negative. + if i < 0 { + return h + } + + // Pre-define the ordered key sets. + keys := []int{WINK, BLINK, CLOSE, JUMP} + rev := []int{JUMP, CLOSE, BLINK, WINK} + + // Use the reversed key set if the REVERSE bit is set. + if i&REVERSE != 0 { + keys = rev + } + + // Build the string slice based on the bitmask. + for _, k := range keys { + if i&k != 0 { + h = append(h, m[k]) + } + } + + return h +} + +// Revision 1 benchmark: +// +// PASS +// BenchmarkHandshake-12 2000000 718 ns/op diff --git a/secret_handshake_test.go b/secret_handshake_test.go new file mode 100644 index 0000000..65fd058 --- /dev/null +++ b/secret_handshake_test.go @@ -0,0 +1,43 @@ +package secret + +import ( + "reflect" + "testing" +) + +var tests = []struct { + code int + h []string +}{ + {1, []string{"wink"}}, + {2, []string{"double blink"}}, + {4, []string{"close your eyes"}}, + {8, []string{"jump"}}, + {3, []string{"wink", "double blink"}}, + {19, []string{"double blink", "wink"}}, + {31, []string{"jump", "close your eyes", "double blink", "wink"}}, + {0, nil}, + {-1, nil}, + {32, nil}, + {33, []string{"wink"}}, +} + +func TestHandshake(t *testing.T) { + for _, test := range tests { + h := Handshake(test.code) + // use len() to allow either nil or empty list, because + // they are not equal by DeepEqual + if len(h) == 0 && len(test.h) == 0 { + continue + } + if !reflect.DeepEqual(h, test.h) { + t.Fatalf("Handshake(%d) = %v, want %v.", test.code, h, test.h) + } + } +} + +func BenchmarkHandshake(b *testing.B) { + for i := 0; i < b.N; i++ { + Handshake(31) + } +}