Last active
November 2, 2016 00:52
-
-
Save cedricblondeau/12b92ec0e0175b2ea44dcc044e7fa2e7 to your computer and use it in GitHub Desktop.
Generates all the words that can be made for given a phone number.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package phoneletters | |
import ( | |
"bytes" | |
"strconv" | |
"strings" | |
) | |
// Generator is a word generator for phone numbers | |
type Generator struct { | |
lists [][]byte | |
} | |
// NewGenerator creates a new word generator instance for a given phone number | |
func NewGenerator(s string) Generator { | |
g := Generator{} | |
g.lists = lists(parse(s)) | |
return g | |
} | |
// Words function generates all the words that can be made | |
func (g Generator) Words(f func(b []byte)) { | |
g.generate(0, make([]byte, len(g.lists)), f) | |
} | |
// generate function works like an odometer and recursively generates a list of words | |
func (g Generator) generate(index int, word []byte, f func([]byte)) { | |
if index == len(word) { | |
f(word) | |
return | |
} | |
for _, letter := range g.lists[index] { | |
word[index] = letter | |
g.generate(index+1, word, f) | |
} | |
} | |
// parse function parses a string and returns a list of digits | |
func parse(s string) []int { | |
result := []int{} | |
digits := strings.Split(s, "") | |
for _, digit := range digits { | |
i, err := strconv.Atoi(digit) | |
if err != nil { | |
continue | |
} | |
result = append(result, i) | |
} | |
return result | |
} | |
// lists returns the lists of possible characters for a given list of digits | |
func lists(digits []int) [][]byte { | |
pad := bytes.Split([]byte("0:1:ABC:DEF:GHI:JKL:MNO:PQRS:TUV:WXYZ"), []byte(":")) | |
result := [][]byte{} | |
for _, digit := range digits { | |
result = append(result, pad[digit]) | |
} | |
return result | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package phoneletters | |
import ( | |
"bytes" | |
"testing" | |
"github.com/stretchr/testify/assert" | |
) | |
func TestParse(t *testing.T) { | |
assert.Equal(t, []int{2, 3, 4, 5}, parse("2345")) | |
assert.Equal(t, []int{1, 2, 3, 4, 5}, parse("12345")) | |
assert.Equal(t, []int{5, 5, 5, 7, 7, 7, 8, 8, 9, 9}, parse("(555) 777-8899")) | |
assert.Equal(t, []int{0, 3, 4, 5}, parse("#: (0) 3-4-5")) | |
} | |
func TestLists(t *testing.T) { | |
expected := bytes.Split([]byte("ABC:DEF"), []byte(":")) | |
result := lists([]int{2, 3}) | |
assert.Equal(t, expected, result) | |
} | |
func TestWords(t *testing.T) { | |
g := NewGenerator("23") | |
result := []string{} | |
f := func(b []byte) { | |
result = append(result, string(b)) | |
} | |
g.Words(f) | |
expected := []string{"AD", "AE", "AF", "BD", "BE", "BF", "CD", "CE", "CF"} | |
assert.Equal(t, expected, result) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage
Print/output combinations
Store combinations in a slice