Go
golang
どう書く
yhpg

オフラインリアルタイムどう書く E20 の実装例

E20の実装( https://qiita.com/Nabetani/items/a68bfd726c59bfc860f7 )を go に移植してみた。
まだ手に馴染んでいない。

実装
package e20

import (
    "strconv"
    "strings"
)

const field = "/01/2345/" +
    "6/789a/b/" +
    "cd/e/fg/h/" +
    "i/jklm/n/" +
    "o/pqr/st/" +
    "uvw/x/yz/" +
    "06cio/u/" +
    "17/d/jpv/" +
    "2/8/ek/q/w/" +
    "39f/l/rx/" +
    "4/a/gmsy/" +
    "5b/hnt/z/"

type vis struct {
    name byte
    d    int
}

func neibours(cur byte) []byte {
    r := []byte{}
    for pos := 1; pos < len(field)-1; pos++ {
        if field[pos] != cur {
            continue
        }
        prev := field[pos-1]
        if prev != '/' {
            r = append(r, prev)
        }
        next := field[pos+1]
        if next != '/' {
            r = append(r, next)
        }
    }
    return r
}

func distance(from, to byte) int {
    visited := make(map[byte]bool)
    q := []vis{{from, 0}}
    for 0 < len(q) {
        cur := q[0].name
        d := q[0].d
        q = q[1:]
        if visited[cur] {
            continue
        }
        visited[cur] = true
        for _, nei := range neibours(cur) {
            if visited[nei] {
                continue
            }
            if nei == to {
                return d + 1
            }
            q = append(q, vis{nei, d + 1})
        }
    }
    return 0
}

func solve(src string) string {
    from := strings.ToLower(src)[0]
    to := strings.ToLower(src)[1]
    d := distance(from, to)
    return strconv.Itoa(d)
}
テスト
package e20

import (
    "testing"
)

func TestE22(t *testing.T) {
    var tests = []struct {
        name  string
        input string
        want  string
    }{
        {"0", "DE", "13"},
        {"1", "EK", "1"},
        {"2", "01", "1"},
        // 中略
        {"49", "OX", "18"},
    }
    for _, test := range tests {
        got := solve(test.input)
        if got != test.want {
            t.Errorf("%v: solve(%q)=%q, want %q\n", test.name, test.input, got, test.want)
        }
    }
}

neibours をきれいに書けていないのが気になっている。(計算に無駄があるのは気になっていない。)

python では無名のタプルで済ましていたところを、go にはタプルがないので(ないよね?)、vis とかいうやる気のない名前をつけてみた。

深さ優先探索の部分は順当に書けているのではないかと思っている。

最初 field という定数に map という予約語の名前をつけようとして負けてしまった。まだ初心者である。