思いついたので書く
課題設定
与えられた1次元配列を順次捜査して、現在位置からひとつ前を参照しつつ、それと現在の要素とを合成した Range オブジェクトを作りたい
そのとき、処理結果として見たときの範囲は被らないようにしたい
入力値の例
[1, 5, 10]
期待する出力
[0..1, 2..5, 6..10]
書いたコード
if
は振り分けに徹してもらった (`・ω・´)
def solver(list = [], previous = nil, ret = []) return ret if list.size.zero? current = list.shift ret << _ = if previous.nil? Range.new(0, current) else Range.new(previous, current) end solver(list, current + 1, ret) end data = [1, 5, 10] solver(data.sort.uniq) # => [0..1, 2..5, 6..10]
ret << _ =
しているのは、「振り分けと代入」「代入から push」としたほうが、コードを読むときのリズムが保てる気がした- 変数名に
_
を用いているのは 特に用途がret
に push するだけで、他に使わない(「特に限定的な変数」が複数有ったら_foo
,_bar
みたいに名前を付けてあげる) - 「(現在の値の)ひとつまえ」とか後ろとか、時間が関わる部分は ひとが混乱しやすいので、予め最初から使えるように定義して、現在だけ考えればいいようにしておくと、アタマの負担が減らせるかもしれない
Tips: 非破壊操作にこだわるなら、.shift
せず .first
にして、再帰呼び出しの時に solver(list - [current], current + 1, ret)
とかできそう