Report abuse


			
require 'pic'

def count(lines)
  lines.inject(Hash.new(0)) do |counts, line|
    if line =~ %r{GET /ongoing/When/\d\d\dx/(\d\d\d\d/\d\d/\d\d/[^ .]+) }
      counts[$1] += 1
    end
    counts
  end
end

def split(collector, limit, source, lines = [], sets = 0)
  if lines.size >= limit
    spawn { collector.send :result, count(lines) }
    tail { split(collector, limit, source, [], sets + 1) }
  elsif source.eof?
    spawn { collector.send :result, count(lines) }
    collector.send :expecting, sets + 1
  else
    tail { split(collector, limit, source, lines + [source.readline], sets) }
  end
end

def collect(counts = {}, sets = 0, expecting = nil)
  if expecting == sets
    report counts
  else
    receive do |match|
      match.when :result do |_, result|
        counts = result.keys.inject(counts) { |h,k| h.merge!(k=>(h[k] || 0) + result[k]) }
        tail { collect(counts, sets + 1, expecting) }
      end
      match.when :expecting do |_, expecting|
        tail { collect(counts, sets, expecting) }
      end
    end
  end
end

def report(counts)
  puts "Results are in"
  keys = counts.keys.sort { |a, b| counts[b] <=> counts[a] }
  keys[0 .. 9].each do |key|
    puts "#{counts[key]}: #{key}"
  end
end

collector = spawn { collect }
spawn { split(collector, 10000, ARGF) }