F#で俳句を出力するプログラムを作成してみました

Myoga-SB-SDF-A2

Hello~! ミョウガです!

今朝、Twitterのタイムラインを眺めていたら、「プロ生ちゃん #俳句プログラミング プチコンテスト 2015」という記事を見つけました。

これは、参加待ったなし!

1. 今回のイベントは部門が2つあるよ

今回のイベントでは、俳句を出力するプログラムをコーディングする「俳句を出力するプログラミング部門」とソースコードで俳句を表現する「ソースコードで俳句部門」の2つの部門があるみたい。

2. 早速、F#で作ってみました

とりあえず、「俳句を出力するプログラミング部門」として、俳句をコンソール画面に出力するシンプルなプログラムをF#で作ってみました。

[<EntryPoint>]
let main argv = 
    argv |> Seq.iter( fun p -> p |> printfn "%s" )
    0

※このプログラムは https://gist.github.com/Nia-TN1012/83526ab84bc7e0647aa7bd17a1636c3e で公開されています(※GitHubアカウントの統合のため、ニア側のGistに移動しました)。

動作としては、main関数の引数argvに格納されているコマンドライン引数の値を表示します。

argvはstring型の配列なので、イテレーターでそれぞれの値を列挙して表示しています。

※3行目にある「|>」はパイプライン演算子と言って、複数の関数を連結して1つの繋がった処理にしたり、処理の流れを見やすくしたりすることができます。F#のカレンダープログラミングも参照してみてね。

実行する時は、コマンドライン引数に俳句を半角スペースで5・7・5に区切って入力します。

fs01
ちなみにこれは松尾芭蕉さんの俳句だよ。

実行結果は以下のようになります。

fs01r

まあ、コマンドライン引数を単に列挙しているだけなんだけどね。

3. 縦書きで出力してみよう

俳句といったら、やっぱ縦書きで出力してナンボです!ということで、縦書きでコンソール画面に出力するように改造してみました。

[<EntryPoint>]
let main argv =

    // 文字数1番多い行の文字数を求めます。
    let max = ( argv |> Seq.maxBy( fun a -> a.Length ) ).Length

    // 各行は上で求めた文字数になるように、全角スペースで末尾をパディングします。
    let argv2 = argv |> Array.map( fun a -> a.PadRight( max, ' ' ) )

    // 文字列のを縦書きになるように並び替えて、出力します。
    Array.init max ( fun i -> System.String( [| for j in 0..argv2.Length - 1 -> argv2.[j].[i] |] |> Array.rev ) )
    |> Array.iter( fun v -> v |> printfn "%s" )

    0

※このプログラムは https://gist.github.com/Nia-TN1012/83526ab84bc7e0647aa7bd17a1636c3e で公開されています(※GitHubアカウントの統合のため、ニア側のGistに移動しました)。

動作としては、文字数が最も多い行に合わせて、他の行はPadRightメソッドを使って全角スペースでパディングし、縦書きになるように文字を並び替えて出力してします。

14行目のArray.int関数は要素数と各要素の初期値を求める関数を指定して、配列を生成する関数だよ。

初期値を求める関数には、生成する配列のインデックス(ここではi)を引数にするラムダ式を指定します。

その中では、各行からi番目の文字をそれぞれ取り出したものを配列にしますが、縦書きでは右から始まるから、Array.rev関数で逆順に並び替えます。

これで縦書きで俳句を出力するプログラムの完成です。

fs02r

3. おわりに

今回は「俳句を出力するプログラミング部門」に応募しましたが、「ソースコードで俳句部門」にもチャレンジしてみようかな。

[END]

コメント

タイトルとURLをコピーしました