Hatena::Grouprubyist

trotrの日記

 | 

2008-04-19

"1 3 4 5 7" => "1, 3-5, 7." 18:38

http://builder.japan.zdnet.com/sp/ruby-doukaku-panel/story/0,3800086254,20369264,00.htm?mode=all#comment-1

以下自分なりの回答

#"1 3 4 5 7" => "1, 3-5, 7."
def f lst
  a = lst.split(" ").map{ |e| e.to_i}.sort
  a[1..-1].inject([[a.first]]) do |tmp, e|
    tmp.last.last == e-1? tmp.last << e : tmp << [e]
    tmp
  end.map{ |e| e.size==1? e.first : "#{e.first}-#{e.last}"}.join(", ")
end
f("7 3 4 5 1") # => "1, 3-5, 

こういう処理をしたいときは、速さよりも書きやすさを意識した方がいいのかな?

要素を整理するメソッドと出力に適した形にするメソッドを分けた方がいいかも。

こんな感じに

def f lst
  a = lst.split(" ").map{ |e| e.to_i}.sort
  a[1..-1].inject([[a.first]]) do |tmp, e|
    tmp.last.last == e-1? tmp.last << e : tmp << [e]
    tmp
  end
end

def layout lst
  lst.map{ |e| e.size==1? e.first : "#{e.first}-#{e.last}"}.join(", ")
end
a = f("7 3 4 5 1") # => [[1], [3, 4, 5], [7]]
layout(a) # => "1, 3-5, 7"

#scriptにしたい場合
#layout(f(ARGV)).display

=begin
出力するぎりぎりまで計算が可能な状態を保った方が便利なような気がする。

a = f("3 5 4 2 1 7") # => [[1, 2, 3, 4, 5], [7]]
a.map{ |xs| xs.map{ |n| n*n}} # => [[1, 4, 9, 16, 25], [49]]
のようなこともできるし(意味があるかはともかく)
=end
 |