ある正数以上の数で最小のNの倍数をワンライナーで求める

ワンライナーの前にRubyである正数に最も近いNの倍数を求めるスクリプトを作る。

例として、ある正数を引数で渡して変数given_nrに格納し、Nを8とする。スクリプトファイル名をmultiple.rbとする。

まず考えられる解法は、given_nrをNで割り、余りがでなければgiven_nrを、余りが出れば商に1を足した数にNをかけたものを出力する方法だ。

実行すると以下のように出力される。

Rubyでは商と余りの両方を一度に求めることができるので、以下のようにも書ける。

また余りが0のときgiven_nrを返すのと商 * Nを返すのは同じ意味になるため、次の二通りの方法で書き換えることができる。

方法3のロジックを少し変わった書き方で書いてみる。

<=>で余りと0を比較している。余りがあれば0より大きいということなので1を返し、余りがなければ0と等しいということなので0を返す。

他にも次のように書ける。

余りがあれば1が最小値として返り、余りがなければrが0なので0が最小値として返る。

方法0はgiven_nrが何度も出てきている。今回はgiven_nrを最初にセットしてから使用しているので問題ないが、ワンライナーで書こうとした場合、何度もgiven_nrに相当する式を書くのは都合が悪い。
同様に方法1から方法5も商と余りを変数q, rに代入している点でワンライナーとは厳密には言えなくなる。

ワンライナーで書きたい場合、次のようにすると簡潔に書ける。

given_nrは一度しか出てこないし、商と余りの両方を計算する必要もない。複数回登場するのは定数であるNだけ。
ロジックは、given_nrにNを超えない数を足した上で、Nで割った商に再度Nをかけるというもの。given_nrがNの倍数の時はN - 1の値を足しても変わらず商が倍数のままでいてくれるし、given_nrがNの倍数でない時はN - 1を足すことでgiven_nr以上の数で最小のNの倍数+αの数になり、商を求めてから再度Nをかけることでgiven_nr以上の数で最小のNの倍数が取得できる。

ワンライナーで実際に書いてみる。

ちなみに、「ある正数以上の数で最小のNの倍数を求める」方法を書いてきたが、「ある正数以下の数で最小のNの倍数を求める」方法は最後のワンライナーの方法のみになる。

商と余りの考え方で書いてもいいのだが、実際には上記と全く同じ式に収斂していく。

-Ruby
-