diff --git a/brc.exs b/brc.exs index 7df0fbe..7c10e74 100644 --- a/brc.exs +++ b/brc.exs @@ -7,7 +7,38 @@ defmodule Brc do require Logger def run(path) do - for {city, [min, max, mean]} <- parse_file(path) do + compute_file(path) + |> output_results() + end + + def compute_file(path) do + Logger.info("computing from file #{path}") + + File.stream!(path) + |> Flow.from_enumerable() + |> Flow.map(&parse_line/1) + |> Flow.partition(key: {:elem, 0}) + |> Flow.reduce(fn -> %{} end, &update_city_temp_map/2) + end + + def update_city_temp_map({city, temp}, acc) do + Map.update(acc, city, [temp, temp, temp], + fn [prev_min, prev_max, mean] -> + [ + min(prev_min, temp), + max(prev_max, temp), + (mean + temp) / 2 + ] + end) + end + + def parse_line(line) do + [city, temp_text] = String.trim(line) |> String.split(";") + {city, String.to_float(temp_text)} + end + + def output_results(results) do + for {city, [min, max, mean]} <- results do "#{city}=#{min}/#{max}/#{Float.round(mean, 1)}" end |> Enum.sort(Cldr.Collation) @@ -15,25 +46,7 @@ defmodule Brc do |> then(fn out -> "{" <> out <> "}" end) |> IO.puts() end - - def parse_file(path) do - Logger.info("parse file #{path}") - - File.stream!(path) - |> Flow.from_enumerable() - |> Flow.map(&parse_line/1) - |> Flow.partition() - |> Flow.reduce(fn -> %{} end, fn {city, temp}, acc -> - Map.update(acc, city, [temp, temp, temp], fn [prev_min, prev_max, mean] -> - [min(prev_min, temp), max(prev_max, temp), (mean + temp) / 2] - end) - end) - end - - def parse_line(line) do - [city, temp] = String.trim(line) |> String.split(";") - {city, String.to_float(temp)} - end end -Brc.run("./measurements.txt") +{path, _} = System.argv() |> List.pop_at(0, "./measurements.txt") +Brc.run(path)