| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- open Stdio
- open Str
- let read_input =
- let rec aux rules updates=
- let line = In_channel.input_line In_channel.stdin in
- match line with
- | None -> rules, updates
- | Some x -> if (Str.string_match (regexp {|[0-9]+|[0-9]+|}) x 0) then
- let z = (List.map int_of_string (Str.split (regexp {|||}) x)) in
- aux ((List.nth z 0, List.nth z 1)::rules) updates else
- (if (Str.string_match (regexp {|[0-9]+\|,|}) x 0) then
- aux rules ((List.map int_of_string (Str.split (regexp {|,|}) x))::updates) else aux rules updates)
- in
- aux [] []
- ;;
- let rules_graph = (fst read_input)
- let updates = (snd read_input)
- let neighbors a =
- let aux g a =
- let edge l (b, c) = if b = a then (c,'a') :: l
- else if c = a then (b,'b') :: l
- else l in
- List.fold_left edge [] g in
- aux rules_graph a
- ;;
- let rec get_order nei = function
- | (n,o)::tl -> if (nei == n) then o else get_order nei tl
- | [] -> 'u'
- ;;
- let rec is_page_ordered neighbors_p = function
- | [] -> true
- | hd :: tl -> if ((get_order hd neighbors_p) == 'a') then
- is_page_ordered neighbors_p tl else false
- ;;
- let get_middle_page u = let u_len = List.length u in List.nth u (u_len/2);;
- let solve =
- let rec is_valid_update u =
- match u with
- | hd :: tl ->
- (let hd_neighbors = neighbors hd in
- if (is_page_ordered hd_neighbors tl) then (is_valid_update tl) else false
- )
- | [] -> true
- in
- let rec aux accum = function
- | [] -> accum
- | hd::tl -> if (is_valid_update hd) then aux (accum + get_middle_page hd) tl
- else aux accum tl in
- aux 0 updates
- ;;
- let () = printf "Total: %d\n" solve
|