DEV Community

Discussion on: Daily Challenge #50 - Number Neighbor

Collapse
 
dak425 profile image
Donald Feury

This was a little harder, at least to me it was.

phone_number.go

package phonenumbers

// PhoneNeighbors returns all the phone numbers that are adjacent to the given phone number
func PhoneNeighbors(phone string) []string {
    numbers := []string{}

    if phone == "" {
        return numbers
    }

    runes := []rune(phone)

    for i, r := range runes {
        // Copy the phone number so we can replace the current digit with its neighbors during the loop
        instance := append(runes[:0:0], runes...)

        // Get the neighbors of this digit
        n := neighbors(r)

        // Loop over the neighbors
        for _, num := range n {
            // Replace the digit at this index with the neighbor and append the result to the slice
            instance[i] = num
            numbers = append(numbers, string(instance))
        }
    }

    return numbers
}

func neighbors(number rune) []rune {
    switch number {
    case '0':
        return []rune{'8'}
    case '1':
        return []rune{'2', '4'}
    case '2':
        return []rune{'1', '3', '5'}
    case '3':
        return []rune{'2', '6'}
    case '4':
        return []rune{'1', '5', '7'}
    case '5':
        return []rune{'2', '4', '6', '8'}
    case '6':
        return []rune{'3', '5', '9'}
    case '7':
        return []rune{'4', '8'}
    case '8':
        return []rune{'0', '5', '7', '9'}
    case '9':
        return []rune{'6', '8'}
    default:
        return []rune{}
    }
}

phone_number_test.go

package phonenumbers

import "testing"

var testCases = []struct {
    description string
    input       string
    expected    []string
}{
    {
        "empty string",
        "",
        []string{},
    },
    {
        "single digit",
        "5",
        []string{"2", "4", "6", "8"},
    },
    {
        "many digits",
        "4531",
        []string{
            "1531",
            "5531",
            "7531",
            "4231",
            "4431",
            "4631",
            "4831",
            "4521",
            "4561",
            "4532",
            "4534",
        },
    },
}

func equal(result []string, expected []string) bool {
    if len(result) != len(expected) {
        return false
    }

    for i := range result {
        if result[i] != expected[i] {
            return false
        }
    }

    return true
}

func TestPhoneNeighbors(t *testing.T) {
    for _, test := range testCases {
        if result := PhoneNeighbors(test.input); !equal(result, test.expected) {
            t.Fatalf("FAIL: %s - PhoneNeighbors(%s): %v - expected: %v", test.description, test.input, result, test.expected)
        }
        t.Logf("PASS: %s", test.description)
    }
}