2018年11月の日能研の広告の問題を力づくで解くページを見かけた
ので,私は Go 言語で解いてみる。
package main
import "fmt"
func Permutations(cards []int) <-chan []int {
ch := make(chan []int)
go func() {
defer close(ch)
perm(ch, make([]int, 0, len(cards)), cards)
}()
return ch
}
func dup(list []int) []int {
l := make([]int, len(list), cap(list))
copy(l, list)
return l
}
func perm(ch chan<- []int, list []int, rest []int) {
if len(rest) == 0 {
ch <- dup(list)
return
}
for i, v := range rest {
restx := dup(rest)
restx = append(restx[:i], restx[i+1:]...)
listx := append(list, v)
perm(ch, listx, restx)
}
}
func list2num(list []int) int {
v := 0
for i, t := len(list)-1, 1; i >= 0; i, t = i-1, t*10 {
v += list[i] * t
}
return v
}
func main() {
for p := range Permutations([]int{1, 2, 3, 4, 5, 6}) {
res := true
for i := 2; i <= 6; i++ {
if list2num(p[:i])%i != 0 {
res = false
break
}
}
if res {
fmt.Println(list2num(p))
}
}
}
これで問題なく動作する。
標準ライブラリには順列を生成する関数はないし reduce のような気の利いた高階関数もないので,ひたすら for 文で回します(笑)
特に Go 言語っぽいトピックはないけど,強いて挙げるなら「配列は値だけど slice は配列への参照(単なるポインタじゃない)を表す」というところだろうか。なので slice の複製を作るのに dup()
関数みたいなのを用意する必要があるわけですね。
あとは順列を生成するのに goroutine でジェネレータ・パターンを構成していることだろうか。