Twitter: @kinaba
FPIAT やってみました。
あなたの関数型指数は -0.401405312902983 です。正が関数型、負が手続き型です。
「いいor手続き型→e」が「いいor関数型→e」のタスクより先に来たので そっちに過剰適応しちゃった感も多少あるけれど、 しかし、嫌関厨な私が見事に見抜かれてて面白いなーと思いました。ひとの結果を見ても 結構合ってる気がする。 あと、なぜかFortranを関数型言語と判断してしまうことが多かった。なんでだ自分。
らへんがぱっと見楽しそう。
mame君の「ランキングの集計」を見て、 足りてないのは今流行のprev/succではないか、などと思ってみた。無理矢理。
ary = %w(foo bar foo baz foo bar qux foo bar qux quux)
n = 3
# 回数をカウントする
count = Hash.new { 0 }
ary.each {|x| count[x] += 1 }
prev = nil # ほげ
# (1~n位)( 回数の多い順 )
(1..n).zip( count.sort_by{|_,v|-v} ) do |i,(k,v)|
puts "#{ i } 位:" if v != prev
puts "- #{ k }"
prev = v # ふが
end
# って、書いてから気づいたけど、これだとオリジナルの動作と違う。
# 同率n位を全部出せるようにして、あともーちょい素直なコードにすると、こうかなあ:
#
# count.sort_by{|_,v|v}.reverse.each_with_index do |(k,v),i| i+=1
# if v != prev
# break if i > n
# puts "#{ i } 位:"
# end
# puts "- #{ k }"
#
# prev = v
# end
#
# あと、順位(#{ i }位)ごとにまとめて何か処理を変えたくなった場合、
# 回数→[文字列] のハッシュを経由してるmame版と違ってこっちはめんどい。
自分で順位indexのインクリメント管理するのはヤだし、 first(n).each_with_index では0-originになるのが読みやすさの面で耐えられないので、 手抜きスクリプトで順位表示するときは (1..n).zip を好んで使ってます。 ただし size < n のとき破綻するので、マジメに書くならどっかで ary.size との min を取るなりなんなり。
あと sort_by{|_,v|-v} よりは、sort_by{|_,v|v}.reverse の方がお行儀良いんですかね。よくわからない。 ここは効率の問題ではなくてですね、 自分の感覚では、ここでやりたいことは「vでソートしてから逆順に列挙」ではなく「vで逆順にソートする」 なのです。「sort.reverse」ではどうも頭の中で「逆順にソートする」とは読めなくて…、 あとで読み返すときに、ここ何やってんだろ?と数秒詰まってしまいます。 sort_by{|_,v|-v} なら vの逆(-)で(by)ソート(sort) ってコードに書いてある。
というかそもそも、どの言語でも、逆順ソートする処理はまとめて1個のメソッド/関数として用意されてていいと思う。 sort と sort.reverse じゃなくて、昇順ソートする sort< と降順ソートする sort> の 二系統があれば迷わないし見た目もわかりやすいです、たぶん。記号が使えない言語なら sort_mM と sort_Mm とか。 なんか凄く話がそれた。
わああ ょゎさんのコード と丸かぶりだった!