solve_2.ml 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. open Stdio
  2. open Str
  3. let get_instructions_byregexp re line =
  4. let rec aux pos list_positions =
  5. try
  6. let start_pos = search_forward re line pos in
  7. aux (match_end ()) (list_positions@[start_pos])
  8. with Not_found -> list_positions
  9. in
  10. aux 0 []
  11. ;;
  12. let active_regions x =
  13. let list_dos_positions = get_instructions_byregexp (regexp {|do()|}) x in
  14. let list_donts_positions = get_instructions_byregexp (regexp {|don't()|}) x in
  15. let rec aux do_flag l_do l_dont pos res =
  16. if do_flag then
  17. (match l_do with
  18. | hd::tl -> if (hd >= pos) then (aux false tl l_dont hd (res@[hd])) else (aux true tl l_dont pos res)
  19. | [] -> res)
  20. else
  21. (match l_dont with
  22. | hd::tl -> if (hd >= pos) then (aux true l_do tl hd (res@[hd])) else (aux false l_do tl pos res)
  23. | [] -> res)
  24. in
  25. aux false list_dos_positions list_donts_positions 0 [0]
  26. ;;
  27. let rec is_active_mul mul_pos = function
  28. | a :: b :: tl -> (if (a<= mul_pos) then
  29. (if (mul_pos <= b) then true
  30. else is_active_mul mul_pos tl)
  31. else false)
  32. | [a] -> mul_pos >= a
  33. | [] -> false
  34. let parse_mult_instruction line=
  35. let active_regions_list = active_regions line in
  36. let r = regexp {|mul( *\([0-9][0-9]?[0-9]?\) *, *\([0-9][0-9]?[0-9]?\) *)|} in
  37. let rec aux pos accum=
  38. try
  39. let mul_pos = search_forward r line pos in
  40. if (is_active_mul mul_pos active_regions_list) then
  41. (let x = float_of_string (matched_group 1 line) in
  42. let y = float_of_string (matched_group 2 line) in
  43. aux (match_end ()) (accum + int_of_float (x *. y)))
  44. else
  45. aux (match_end ()) accum
  46. with Not_found -> accum
  47. in
  48. aux 0 0
  49. ;;
  50. let solve =
  51. let rec one_string input =
  52. let line = In_channel.input_line In_channel.stdin in
  53. match line with
  54. | None -> input
  55. | Some x -> one_string (input ^ x)
  56. in
  57. parse_mult_instruction (one_string "")
  58. ;;
  59. let () = printf "Total: %d\n" (solve)