@@ -20,11 +20,11 @@ defmodule ReadMeasurements.App do
20
20
21
21
workers = Enum . map ( 1 .. worker_count , fn _ ->
22
22
spawn_link ( fn ->
23
- worker_main ( parent , "" , % { } )
23
+ worker_main ( parent , "" )
24
24
end )
25
25
end )
26
26
27
- { :ok , file } = :prim_file . open ( filename , [ :binary , :read ] )
27
+ { :ok , file } = :prim_file . open ( filename , [ :raw , : binary, :read ] )
28
28
result =
29
29
try do
30
30
read_file ( file , workers )
@@ -40,32 +40,24 @@ defmodule ReadMeasurements.App do
40
40
|> ReadMeasurements . output ( )
41
41
end
42
42
43
- def worker_main ( parent , << >> , result ) do
43
+ def worker_main ( parent , << >> ) do
44
44
send ( parent , { :checkin , self ( ) } )
45
45
receive do
46
46
:eos ->
47
- send ( parent , { :result , result } )
47
+ # we don't have to care about the type unlike the erlang version
48
+ # so we can just take the process dictionary as is
49
+ send ( parent , { :result , :erlang . get ( ) } )
48
50
:ok
49
51
50
52
{ :chunk , bin } ->
51
- worker_main ( parent , bin , result )
53
+ worker_main ( parent , bin )
52
54
end
53
55
end
54
56
55
- def worker_main ( parent , rest , result ) do
56
- [ ws , rest ] = :binary . split ( rest , ";" )
57
- { temp , << "\n " , rest :: binary >> } = binary_split_to_fixed_point ( rest )
58
-
57
+ def worker_main ( parent , rest ) do
59
58
worker_main (
60
59
parent ,
61
- rest ,
62
- case Map . fetch ( result , ws ) do
63
- :error ->
64
- Map . put ( result , ws , { 1 , temp , temp , temp } )
65
-
66
- { :ok , { count , total , mn , mx } } ->
67
- Map . put ( result , ws , { count + 1 , total + temp , min ( mn , temp ) , max ( mx , temp ) } )
68
- end
60
+ process_line ( rest )
69
61
)
70
62
end
71
63
@@ -124,26 +116,54 @@ defmodule ReadMeasurements.App do
124
116
end
125
117
end
126
118
119
+ defp process_line ( rest ) do
120
+ parse_weather_station ( rest , rest , 0 )
121
+ end
122
+
123
+ defp parse_weather_station ( bin , << ";" , _rest :: binary >> , count ) do
124
+ << ws :: binary - size ( count ) , ";" , rest :: binary >> = bin
125
+ parse_temp ( rest , ws )
126
+ end
127
+
128
+ defp parse_weather_station ( bin , << _c , rest :: binary >> , count ) do
129
+ parse_weather_station ( bin , rest , count + 1 )
130
+ end
131
+
127
132
defmacrop char_to_num ( c ) do
128
133
quote do
129
- unquote ( c ) - ?0
134
+ ( unquote ( c ) - ?0 )
130
135
end
131
136
end
132
137
133
- defp binary_split_to_fixed_point ( << ?- , d2 , d1 , ?. , d01 , rest :: binary >> ) do
134
- { - ( char_to_num ( d2 ) * 100 + char_to_num ( d1 ) * 10 + char_to_num ( d01 ) ) , rest }
138
+ defp parse_temp ( << ?- , d2 , d1 , ?. , d01 , "\n " , rest :: binary >> , ws ) do
139
+ commit_entry ( ws , - ( char_to_num ( d2 ) * 100 + char_to_num ( d1 ) * 10 + char_to_num ( d01 ) ) )
140
+ rest
141
+ end
142
+
143
+ defp parse_temp ( << ?- , d1 , ?. , d01 , "\n " , rest :: binary >> , ws ) do
144
+ commit_entry ( ws , - ( char_to_num ( d1 ) * 10 + char_to_num ( d01 ) ) )
145
+ rest
135
146
end
136
147
137
- defp binary_split_to_fixed_point ( << ?- , d1 , ?. , d01 , rest :: binary >> ) do
138
- { - ( char_to_num ( d1 ) * 10 + char_to_num ( d01 ) ) , rest }
148
+ defp parse_temp ( << d2 , d1 , ?. , d01 , "\n " , rest :: binary >> , ws ) do
149
+ commit_entry ( ws , char_to_num ( d2 ) * 100 + char_to_num ( d1 ) * 10 + char_to_num ( d01 ) )
150
+ rest
139
151
end
140
152
141
- defp binary_split_to_fixed_point ( << d2 , d1 , ?. , d01 , rest :: binary >> ) do
142
- { char_to_num ( d2 ) * 100 + char_to_num ( d1 ) * 10 + char_to_num ( d01 ) , rest }
153
+ defp parse_temp ( << d1 , ?. , d01 , "\n " , rest :: binary >> , ws ) do
154
+ commit_entry ( ws , char_to_num ( d1 ) * 10 + char_to_num ( d01 ) )
155
+ rest
143
156
end
144
157
145
- defp binary_split_to_fixed_point ( << d1 , ?. , d01 , rest :: binary >> ) do
146
- { char_to_num ( d1 ) * 10 + char_to_num ( d01 ) , rest }
158
+ defp commit_entry ( ws , temp ) do
159
+ # write it to the process dictionary
160
+ case :erlang . get ( ws ) do
161
+ :undefined ->
162
+ :erlang . put ( ws , { 1 , temp , temp , temp } )
163
+
164
+ { count , total , mn , mx } ->
165
+ :erlang . put ( ws , { count + 1 , total + temp , min ( mn , temp ) , max ( mx , temp ) } )
166
+ end
147
167
end
148
168
end
149
169
0 commit comments