LoginSignup
0

More than 3 years have passed since last update.

posted at

updated at

日能研の問題をGo言語で力づくで解いてみた(2018/11)

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 でジェネレータ・パターンを構成していることだろうか。

参考

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
What you can do with signing up
0