知人のRubyコードを勝手に添削してみました
ライブドアブログ(livedoor Blog)| 読みたいブログが見つかる
勝手に添削をさらに勝手に書き直す - takkan_mのNo planな日常
僕も添削してみました。縛りは他の方と同じで「プログラムの構造など、劇的な変化はしない。例: クラスやメソッド構造など」です。以下、id:takkan_mさんのをベースに変更しています。
#!/usr/bin/env ruby require 'pp' require 'enumerator' #def functions def make_cluster(centroid, num_array) num_array.partition {|v| (centroid[0] - v) ** 2 < (centroid[1] - v) ** 2 } end def make_centroid(cluster) cluster.map do | c | c.empty? ? 0 : c.inject {|r, v| r + v } / c.size end end def calc_var(centroid, cluster) cluster.enum_for(:each_with_index).map do |clu, i| clu.inject(0.0) {|r, v| r + (v - centroid[i]) ** 2 } end end #end def functions num_array = [1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 6.0, 7.5, 8.0, 8.5, 9.0, 10.0] new_centroid = [0.0, 1.0] centroid = [0.0, 0.0] counter = 0 while centroid != new_centroid puts if counter != 0 centroid = new_centroid cluster = make_cluster(centroid, num_array) puts "step#{counter}:" puts 'centroid:' pp centroid #calc var puts 'var:' pp calc_var(centroid, cluster) puts 'cluster:' pp cluster new_centroid = make_centroid(cluster) counter += 1 end
変更内容はこんな感じです。
- num_array.selectのところは、Enumerable#partitionを使って書けました。
- c.size == 0は、Array#empty?に変更しました。
- cluster.zipはHaskellでは定石なのですが、Rubyではいまひとつ自信がありません。ここではenumeratorモジュールのObject#enum_forを使ってみました。
- 改行を表示するputsを前に持ってきて、最初の一回は除外するようにしました(前のプログラムとの互換性のため)。あとただ改行するだけなので、引数の"\n"は省略しました。
- puts 'centroid:'など、バックスラッシュ記法や変数展開のない文字列はシングルクォートで囲むようにしました。