LoginSignup
6
7

More than 5 years have passed since last update.

go言語のchannelでムダに竹内関数をまわす

Posted at

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すごい。
そんじゃーね。

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7