数列問題を関数的に解いてみる

Rubyでどう書く?:連続した数列を範囲形式にまとめたい - builder by ZDNet Japan

苦戦するなんて情けねぇorz

# -*- coding: euc-jp -*-
=begin
=== 仕様

・ 数値は、半角スペースで区切られた文字列で渡されます。
・ 続いている部分は、最初の数値と最後の数値を-(ハイフン)で繋いだ表記にします。
・ 連続が1回の場合(前の数も後ろの数も連続でない)は、-(ハイフン)では繋ぎません。
・ 出力は、「,」(カンマ)と半角スペースで区切られた文字列でなければなりません。

=== 例

・ "1 2 3" => "1-3."
・ "1 2 3 5 7 8" => "1-3, 5, 7-8."
・ "1 3 4 5 7" => "1, 3-5, 7."

=end
require 'rubygems'
require 'expectations'
 # !> method redefined; discarding old expects
def fmt(seq, last=nil, str="", successivep=false)
  if seq.empty?
    successivep ? "#{str}-#{last}." : "#{str}."
  elsif last.nil?
    fmt seq[1..-1], seq.first, "#{str}#{seq.first}", false
  elsif seq.first - 1 == last
    fmt seq[1..-1], seq.first, str, true
  elsif successivep
    fmt seq[1..-1], seq.first, "#{str}-#{last}, #{seq.first}", false
  else
    fmt seq[1..-1], seq.first, "#{str}, #{seq.first}", false
  end
end

Expectations do
  expect "1-3." do
    fmt [1, 2, 3]
  end

  expect "1-3, 5, 7-8." do
    fmt [1, 2, 3, 5, 7, 8]
  end

  expect "1, 3-5, 7." do
    fmt [1, 3, 4, 5, 7]
  end
end
# >> Expectations ...
# >> Finished in 0.001 seconds
# >> 
# >> Success: 3 fulfilled