オフラインリアルタイムどう書く E16 の実装例( Go )
問題 : http://nabetani.sakura.ne.jp/hena/orde16nontri/
実装リンク集 : https://qiita.com/Nabetani/items/3525da55601bdf55316e
順当に https://qiita.com/Nabetani/items/c2e4a0ee80bcd28c1636 を移植した。
実装
package e16
import (
"math"
"strconv"
"strings"
)
func impl(num int64) int64 {
sb := strconv.FormatInt(num, 2)
zero3 := strings.Index(sb, "000")
one3 := strings.Index(sb, "111")
if zero3 < 0 && one3 < 0 {
return num
}
if zero3 < 0 {
zero3 = math.MaxInt32
}
if one3 < 0 {
one3 = math.MaxInt32
}
if zero3 < one3 {
head := sb[0:zero3]
tail := strings.Repeat("0", len(sb)-zero3-3)
newnum, _ := strconv.ParseInt(head+"001"+tail, 2, 64)
return impl(newnum)
} else {
head := sb[0:one3]
tail := strings.Repeat("1", len(sb)-one3)
newnum, _ := strconv.ParseInt(head+tail, 2, 64)
return impl(newnum + 1)
}
}
func solve(src string) string {
num, _ := strconv.ParseInt(src, 10, 64)
return strconv.FormatInt(impl(num+1), 10)
}
テスト
package e16
import (
"testing"
)
func Test(t *testing.T) {
var tests = []struct {
name string
input string
want string
}{
{"0", "1441", "1444"},
{"1", "1", "2"},
{"2", "2", "3"},
{"3", "3", "4"},
// 中略
{"40", "1072693248", "1227133513"},
}
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)
}
}
}
ruby では正規表現だった部分を strings.Index
に変更した。
"000"
と "111"
のどちらが左側にあるのかの処理がちょっとわかりにくい感じなのがよろしくないように思うけど、ほかにいい方法が思いつかなかった。
math.MaxInt32
や math.MaxInt64
はあっても math.MaxInt
がないのが残念。