|
|
@@ -0,0 +1,66 @@
|
|
|
+open Stdio
|
|
|
+open Str
|
|
|
+
|
|
|
+let get_instructions_byregexp re line =
|
|
|
+ let rec aux pos list_positions =
|
|
|
+ try
|
|
|
+ let start_pos = search_forward re line pos in
|
|
|
+ aux (match_end ()) (list_positions@[start_pos])
|
|
|
+ with Not_found -> list_positions
|
|
|
+ in
|
|
|
+ aux 0 []
|
|
|
+;;
|
|
|
+
|
|
|
+let active_regions x =
|
|
|
+ let list_dos_positions = get_instructions_byregexp (regexp {|do()|}) x in
|
|
|
+ let list_donts_positions = get_instructions_byregexp (regexp {|don't()|}) x in
|
|
|
+ let rec aux do_flag l_do l_dont pos res =
|
|
|
+ if do_flag then
|
|
|
+ (match l_do with
|
|
|
+ | hd::tl -> if (hd >= pos) then (aux false tl l_dont hd (res@[hd])) else (aux true tl l_dont pos res)
|
|
|
+ | [] -> res)
|
|
|
+ else
|
|
|
+ (match l_dont with
|
|
|
+ | hd::tl -> if (hd >= pos) then (aux true l_do tl hd (res@[hd])) else (aux false l_do tl pos res)
|
|
|
+ | [] -> res)
|
|
|
+ in
|
|
|
+ aux false list_dos_positions list_donts_positions 0 [0]
|
|
|
+;;
|
|
|
+
|
|
|
+let rec is_active_mul mul_pos = function
|
|
|
+| a :: b :: tl -> (if (a<= mul_pos) then
|
|
|
+ (if (mul_pos <= b) then true
|
|
|
+ else is_active_mul mul_pos tl)
|
|
|
+ else false)
|
|
|
+| [a] -> mul_pos >= a
|
|
|
+| [] -> false
|
|
|
+
|
|
|
+
|
|
|
+let parse_mult_instruction line=
|
|
|
+ let active_regions_list = active_regions line in
|
|
|
+ let r = regexp {|mul( *\([0-9][0-9]?[0-9]?\) *, *\([0-9][0-9]?[0-9]?\) *)|} in
|
|
|
+ let rec aux pos accum=
|
|
|
+ try
|
|
|
+ let mul_pos = search_forward r line pos in
|
|
|
+ if (is_active_mul mul_pos active_regions_list) then
|
|
|
+ (let x = float_of_string (matched_group 1 line) in
|
|
|
+ let y = float_of_string (matched_group 2 line) in
|
|
|
+ aux (match_end ()) (accum + int_of_float (x *. y)))
|
|
|
+ else
|
|
|
+ aux (match_end ()) accum
|
|
|
+ with Not_found -> accum
|
|
|
+ in
|
|
|
+ aux 0 0
|
|
|
+;;
|
|
|
+
|
|
|
+let solve =
|
|
|
+ let rec one_string input =
|
|
|
+ let line = In_channel.input_line In_channel.stdin in
|
|
|
+ match line with
|
|
|
+ | None -> input
|
|
|
+ | Some x -> one_string (input ^ x)
|
|
|
+ in
|
|
|
+ parse_mult_instruction (one_string "")
|
|
|
+;;
|
|
|
+
|
|
|
+let () = printf "Total: %d\n" (solve)
|