# Copied with little modifications from: https://github.com/rubinius/rubinius-benchmark/blob/master/real_world/bench_degree_days.rb class DegreeDays def initialize(@daily_temperatures : Array(Array(Int32)), @options = {} of String => Float64) end property :daily_temperatures def calculate heating = 0.0 cooling = 0.0 heating_days = 0.0 cooling_days = 0.0 daily_temperatures.each do |day| heating_today = heating_day(day) cooling_today = cooling_day(day) if heating_today heating_days += 1 heating += heating_today end if cooling_today cooling_days += 1 cooling += cooling_today end end { "heating" => heating, "cooling" => cooling, "heating_days" => heating_days, "cooling_days" => cooling_days, } end private def sum(ary) ary.reduce(0) { |a, i| a + i } end private def avg(ary) sum(ary).to_f / ary.size.to_f end private def heating_day(temps) heat = avg temps.map { |temp| heating_degree(temp) } (heat > heating_threshold) ? heat : nil end private def cooling_day(temps) cool = avg temps.map { |temp| cooling_degree(temp) } (cool > cooling_threshold) ? cool : nil end private def heating_degree(temp) deg = base_temperature - (temp + heating_insulation) {deg, 0}.max end private def cooling_degree(temp) deg = (temp - cooling_insulation) - base_temperature {deg, 0}.max end private def base_temperature @options["base_temperature"]? || 65.0 end private def heating_insulation @options["heating_insulation"]? || insulation_factor || 3 end private def cooling_insulation @options["cooling_insulation"]? || insulation_factor || 0 end private def insulation_factor @options["insulation_factor"]? end private def heating_threshold @options["heating_threshold"]? || threshold || 6 end private def cooling_threshold @options["cooling_threshold"]? || threshold || 3 end private def threshold @options["threshold"]? end end (ARGV[0]? || 300).to_i.times do |i| days_in_year = 365 hours_in_day = 24 hot_day = Array.new(hours_in_day, 92) cold_day = Array.new(hours_in_day, 37) # 182 hot days + 183 cold days temperatures = Array.new((days_in_year / 2.0).floor.to_i, hot_day) + Array.new((days_in_year / 2.0).ceil.to_i, cold_day) degree_days = DegreeDays.new(temperatures) res = degree_days.calculate p res if i == 0 end