channelの勉強がてら、竹内関数の入出力をチャンネル経由にする
func Tak(x, y, z int) int {
if x <= y {
return y
}
return Tak(Tak(x-1, y, z), Tak(y-1, z, x), Tak(z-1, x, y))
}
竹内関数とはこんな感じのもの。
やたらとたらいまわされる。
これをひとつひとつチャンネル経由にしたらどうなるか
さらにたらいまわされるに違いないということで、やってみた。
名前は タケちゃん関数
package main
import (
"fmt"
)
func Tak(x, y, z int) int {
if x <= y {
return y
}
return Tak(Tak(x-1, y, z), Tak(y-1, z, x), Tak(z-1, x, y))
}
func v2c(v int) chan int {
e := make(chan int)
go func() { e <- v }()
return e
}
func Takechan(xc, yc, zc chan int) chan int {
emitter := make(chan int)
go func() {
x, y, z := <-xc, <-yc, <-zc
if x <= y {
emitter <- y
return
}
emitter <- <-Takechan(
Takechan(v2c(x-1), v2c(y), v2c(z)),
Takechan(v2c(y-1), v2c(z), v2c(x)),
Takechan(v2c(z-1), v2c(x), v2c(y)))
}()
return emitter
}
func main() {
fmt.Println(<-Takechan(v2c(14), v2c(6), v2c(5)))
fmt.Println(Tak(13, 6, 5))
}
そこそこ早くうごいた。goroutineすごい。
そんじゃーね。