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
という予約語の名前をつけようとして負けてしまった。まだ初心者である。