Code Aquarium

minazoko's blog -*- 水底のブログ -*-

Clojureで掛け算テーブル

お題はこちら

書きました。少し冗長でしょうか。

条件文はあえて言葉足らずに書きました。「負の数を含めるのか?」という疑問が出ると思いますがそこは各々の判断に任せました。条件に忠実にしたがえば負の数も範囲にはいるはずですが。

 

->> 簡単に解説

make-row-seqはテーブルのヘッダを除いた部分を一行づつ無限に生成するシーケンスを作ります。テーブルを縦方向に見るとすべての列が等差数列で公差は各列のヘッダの値になります。この性質を利用して上から順に加算のみで行を作りづつけます。

make-tableはmake-row-seqを使用して、テーブルを構成するデータを作ります。ヘッダとテーブルのボディ部分は分けたままマップコレクションで返します。

そのマップを受けて、出力用に加工したデータシーケンスを作るのがto-output-seqです。ヘッダとボディの結合と、左上隅の空欄を付加します。

最後にテキストにして出力するのがwrite-tableです。コレクションを整形して出力するのに最適なのはcl-formatですね*1。ただしセルの幅はパラメータによって変わるのでcl-formatを適用する書式文字列をあらかじめformatで作成しています。桁数がもっとも多いのはテーブルボディ部の3隅のどれか、またはヘッダの一番目の項になるはずです。

cl-formatは第一引数にてテキストの出力先を指定できるので、その仕様を活かしたままにしつつ、今回の出題に合わせたインターフェースとなるprint-tableを作りました。

 

->>結果

multitable> (print-table 3 7)
    3  4  5  6  7
 3  9 12 15 18 21
 4 12 16 20 24 28
 5 15 20 25 30 35
 6 18 24 30 36 42
 7 21 28 35 42 49
nil

multitable> (print-table -3 4)
     -3  -2  -1   0   1   2   3   4
 -3   9   6   3   0  -3  -6  -9 -12
 -2   6   4   2   0  -2  -4  -6  -8
 -1   3   2   1   0  -1  -2  -3  -4
  0   0   0   0   0   0   0   0   0
  1  -3  -2  -1   0   1   2   3   4
  2  -6  -4  -2   0   2   4   6   8
  3  -9  -6  -3   0   3   6   9  12
  4 -12  -8  -4   0   4   8  12  16
nil

multitable> (print-table 7 7)
    7
 7 49
nil

multitable> (print-table -1 -1)
   -1
-1  1
nil

multitable> (print-table -1 0)
   -1  0
-1  1  0
 0  0  0
nil

*1:Common Lisp様々です