標準入力を指定行数ごとに分割するプログラム
30分プログラム、その765。標準入力を指定行数ごとに分割するプログラムを作ってました。
SeqとIteratorの違いで多いに苦しみました。ドキュメントはまったく読んでないのですが挙動と名前から類推するに、
xs.take(n)
xsがSeqならxsは変化せずに、Iteratorなら指す先が変化するみたいです。
Iteratorのほうが効率がいい気がしたのですが、使いこなせる気がしなかったのでSeqで書きました。
使い方
$ jot 100 | scala Split 3 "test-%d.tmp" $ ls test-*.tmp test-0.tmp test-15.tmp test-21.tmp test-28.tmp test-4.tmp test-1.tmp test-16.tmp test-22.tmp test-29.tmp test-5.tmp test-10.tmp test-17.tmp test-23.tmp test-3.tmp test-6.tmp test-11.tmp test-18.tmp test-24.tmp test-30.tmp test-7.tmp test-12.tmp test-19.tmp test-25.tmp test-31.tmp test-8.tmp test-13.tmp test-2.tmp test-26.tmp test-32.tmp test-9.tmp test-14.tmp test-20.tmp test-27.tmp test-33.tmp $ cat test-0.tmp 1 2 3 $ cat test-1.tmp 4 5 6
ソースコード
import scala.io.Source import java.io.FileWriter object Split { def partition[T](n : Int, xs : Seq[T]) : Pair[Seq[T], Seq[T]] = (xs.take(n), xs.drop(n)) def split[T](n : Int, xs : Seq[T]) : List[Seq[T]] = { val (ys, zs) = partition(n, xs) if( zs.isEmpty ) List(ys) else ys :: split(n, zs) } def main(args : Array[String]) { val count = args(0).toInt val templ = args(1) val lines = split(count, List.fromIterator(Source.fromInputStream(System.in).getLines)) for((xs,n) <- lines.zipWithIndex){ val path = templ.format(n) val writer = new FileWriter(path) for(x <- xs){ writer.write(x) } writer.close } } }