| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- open Stdio
- let input =
- let line = In_channel.input_line In_channel.stdin in
- match line with
- | None -> ""
- | Some x -> x
- ;;
- let expand dm =
- let rec aux i acc=
- if (i >= String.length dm) then
- acc
- else (if (i == String.length dm -1)
- then
- let id = (i/2) in
- let file_size = (int_of_char dm.[i] - int_of_char '0') in
- let new_encoding = List.init file_size (fun _ -> id) in
- new_encoding@acc
- else
- let id = (i/2) in
- let file_size = (int_of_char dm.[i] - int_of_char '0') in
- let empty_space = (int_of_char dm.[i+1] - int_of_char '0') in
- let new_encoding = (List.init empty_space (fun _ -> -1)) @ (List.init file_size (fun _ -> id)) in
- aux (i+2) (new_encoding@acc))
- in
- aux 0 []
- ;;
- let reverse_list =
- let rec aux acc = function
- | [] -> acc
- | x :: tl -> aux (x::acc) tl
- in
- aux []
- ;;
- let get_dm_and_queue =
- let rec aux acc queue = function
- | [] -> acc, (reverse_list queue)
- | -1 :: tl -> aux (-1::acc) queue tl
- | x :: tl -> aux (x::acc) (x::queue) tl
- in
- aux [] []
- ;;
- let compact dm =
- let reversed, queue = (get_dm_and_queue dm) in
- let len_dm = (List.length queue) in
- let rec aux acc q l=
- if (List.length acc == len_dm) then (reverse_list acc) else
- match l with
- | [] -> (reverse_list acc)
- | -1::tl -> aux ((List.hd q)::acc) (List.tl q) tl
- | x :: tl -> aux (x::acc) q tl
- in
- aux [] queue reversed
- ;;
- let calculate_checksum dm=
- let rec aux id accum = function
- | [] -> accum
- | x::tl -> aux (id+1) (id*x + accum) tl
- in
- aux 0 0 dm;;
-
- let solve =
- let dm = expand input in
- calculate_checksum (compact dm);
- ;;
- let () =
- printf "Total: %d\n" solve;;
|