solve_1.ml 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. open Stdio
  2. open Str
  3. let read_input =
  4. let rec aux rules updates=
  5. let line = In_channel.input_line In_channel.stdin in
  6. match line with
  7. | None -> rules, updates
  8. | Some x -> if (Str.string_match (regexp {|[0-9]+|[0-9]+|}) x 0) then
  9. let z = (List.map int_of_string (Str.split (regexp {|||}) x)) in
  10. aux ((List.nth z 0, List.nth z 1)::rules) updates else
  11. (if (Str.string_match (regexp {|[0-9]+\|,|}) x 0) then
  12. aux rules ((List.map int_of_string (Str.split (regexp {|,|}) x))::updates) else aux rules updates)
  13. in
  14. aux [] []
  15. ;;
  16. let rules_graph = (fst read_input)
  17. let updates = (snd read_input)
  18. let neighbors a =
  19. let aux g a =
  20. let edge l (b, c) = if b = a then (c,'a') :: l
  21. else if c = a then (b,'b') :: l
  22. else l in
  23. List.fold_left edge [] g in
  24. aux rules_graph a
  25. ;;
  26. let rec get_order nei = function
  27. | (n,o)::tl -> if (nei == n) then o else get_order nei tl
  28. | [] -> 'u'
  29. ;;
  30. let rec is_page_ordered neighbors_p = function
  31. | [] -> true
  32. | hd :: tl -> if ((get_order hd neighbors_p) == 'a') then
  33. is_page_ordered neighbors_p tl else false
  34. ;;
  35. let get_middle_page u = let u_len = List.length u in List.nth u (u_len/2);;
  36. let solve =
  37. let rec is_valid_update u =
  38. match u with
  39. | hd :: tl ->
  40. (let hd_neighbors = neighbors hd in
  41. if (is_page_ordered hd_neighbors tl) then (is_valid_update tl) else false
  42. )
  43. | [] -> true
  44. in
  45. let rec aux accum = function
  46. | [] -> accum
  47. | hd::tl -> if (is_valid_update hd) then aux (accum + get_middle_page hd) tl
  48. else aux accum tl in
  49. aux 0 updates
  50. ;;
  51. let () = printf "Total: %d\n" solve