【Scala】permutater

例のごとく解答の一例が載っています。

今回はこちら(anarchy golf - permutater)
順列です。


とりあえずSampleから文字を読み取って、配置の入れ替えをしないといけない
そのためには1文字ずつリスト化していきたいけど、出来るのだろうか
とりあえずやってみる

scala> var st = "ABCD"
st: String = ABCD

scala> st.toList
res: List[Char] = List(A, B, C, D)

ひとつの文字列をリスト化するとこのように1文字ずつリストに格納されるようです。
Int型などの数字は出来ませんが、readLineで返される値はString型なのでNP


これが分かったのがいいものの、上手く並び替える方法が全く出てこない。
たまらず調べてみる、するとこんなページが
順列、組み合わせ、冪集合を生成する | Scala Cookbook

Scalaでは集合を並び替えた順列(permutation)や、組み合わせ(combination, 重複を含まない)、冪集合(power set)などを手軽に生成できる。

ほげっ・・・こんなのがあるのか・・・

早速使ってみる

scala> st.toList.permutations
res: Iterator[List[Char]] = non-empty iterator

Iterator。初めて見る文字列ですね
全くわからないのでこれまた調べてみる

["collections"] - イテレータ - Scala Documentation

イテレータ (Iterator) はコレクションではなく、コレクションから要素を1つづつアクセスするための方法だ。

普通のコレクション型(リストなど)とはまた少し扱いが違うっぽい。
そのうちまとめておこう

これを使ってまずは何も考えずに作る


print(readLine.toList.permutations.map(_.mkString("")).mkString("\n"))

色々と無茶苦茶すぎる気がする・・・
でも一応成功。ついでにtoListをtoSeqに直して69bytes


さらに色々いじってたら、最初のmkStringには("")が必要ないことがわかったので削る

print(readLine.toSeq.permutations.map(_.mkString).mkString("\n"))

65bytes。


擬似的にリストのリストを作って試行錯誤していく。

scala> test
res: List[List[String]] = List(List(A, B), List(C, D)) //リストのリスト(定義済み)

scala> test.map(_.mkString).map(println)
AB
CD
res: List[Unit] = List((), ())



いい感じにまとまったので、permutationsを使ったものに戻してみるも上手く行かず。

scala> l
res: List[String] = List(A, B, C)

scala> l.permutations.map(_.mkString).map(println)
res: Iterator[Unit] = non-empty iterator 

失敗してます。うーんIteratorむずかしい。


mkStringが必要かどうか疑わしいけど、色々試してみても上手く行かなかったのでひとまず65bytesでフィニッシュ。
リストのリストを上手く扱える方法は他にあるのかなー
分かる人がいたらヒントくださいヒント!


この記事でイテレータにまとめるのもなんなので、イテレータについて別の記事でまとめつつ更新していく予定


12.3 追記
コメントより

permutationsは文字列をレシーバとして呼び出すことが出来ます。戻り値の型はIterator[String]。Stringの要素に対してmap(_.mkString)する意味はないですね。

戻り値はString型なのか。コレ必要かな~??と思ってたけどまるまるいらなかったとは。
という訳で削って実行してみる

print(readLine.toSeq.permutations.mkString("\n"))

うわ本当にできちゃったよ・・・コレがなくなったことでpermutationsの扱い方が少しわかったかも。49bytes

さらに、foreachでもイケルよ、というお話なので

readLine.toSeq.permutations.foreach(println)

そんでもって、そもそもtoSeqがいらないことに気づく。

readLine.permutations.foreach(println)

38bytes. あと1byteどこすか。



12.4 追記
12.4といってもさっきの1時間後くらいだけども。37bytesです。

readLine.permutations foreach println

出来たはいいけどなんで成功したかイマイチ分かっていない。

ちなみにダメだった例

readLine.permutations.foreach println

printlnに()がいらないのは引数が1つだから、ってのはわかるんだけどなあ
foreachをperamutationsしたものに対してつかっているかどうかの違い?
.foreach と foreach の違いとは一体。

とりあえずはpermutater完結。