【Scala】echo

解答の一例が含まれますので閲覧は自己責任で。


ゴルフは大人の嗜み。
今日はこちら anarchy golf - echo

入力された文字列を受け取ってそのまま出力する、というもの
問題を解く前に、コードとは別の外部から入力を受け取るクラスなどを整理します


標準入力(プログラム外部からの入力)から値を取得するときに使われるのは主にこの2つ

  • readLine

一行ごとに文字列を取得する。

  • io.Source.stdin

・io.Source.stdin.mkString 
全入力を一つの文字列として取得。
・io.Source.stdin.getLines 
全入力を一行ごとに取得。さらにtoListで列ごとにリスト化出来たりする


とりあえず試しに使ってみる


readLineを使う場合、一行ごとにしか文字列を取得しないのでループさせて一行ずつ取得、出力。というイメージでプログラムを書く

for(s<- 1 to 4) println(readLine)

forで4行分取得と出力を繰り返す。33byte


io.Source.stdin.mkStringを使う場合は一気にプリントすればおっけー

print(io.Source.stdin.mkString)

らくちん。31byte

io.Source.stdin.foreach(print)

mkStringを使わない場合はこんな感じになる。30byte

io.Source.stdin.getLines.toList.foreach(println)

こうすれば各行をリスト化できて、後々フィルターなどをかけやすい。
普通に使いやすそう。長いから今回は使いませんが(48byte)


それではbyteを減らしていきます
ぱっと見どう見てもreadLineの方がbyte数が少ないので、こちらを使っていきます
ちなみにそれぞれ8byte,15byte

while(0<1)println(readLine.r)

while(1<0)で永遠とループを回して、例外が起きた場合に処理を止める、というやり方。
実務では勿論やっちゃダメです。
.rは正規表現オブジェクトを返すString型のメソッドです。


readLineで文字列を読み込んでいくも、文字列がない状態になる=readLineでNullを取得。
Nullはなんのメソッドも持たないからコレおかしいよ!ループ抜けるよ!という感じで無理やり抜けます。


これで29byteです。


Topは27byteですが、27byteクリアするなら上で学んだことは一切使いません。
まあ、お察しください。



おまけ この問題には関係ないけどこの問題関連について調べてて知ったこと

  • mkString リストの各要素の間に文字列を埋め込んだ文字列を返す
scala> List(1,2,3).mkString("-")
res: String = 1-2-3

toStringとかと同じ感覚で使えばいいと思う

  • s String ""の前にsを付けると、文字列中にある$(変数名)が置き換わる。
scala> var w = "world"
w: String = world

scala> s"Hello, $w"
res17: String = Hello, world

""の中で変数を使いたいときに。



入出力に関してはまだまだわからないことが多いから、どんどん慣れていきたいです