naive_solution.ml 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. open Stdio
  2. open Str
  3. let input =
  4. let rec one_string inp=
  5. let line = In_channel.input_line In_channel.stdin in
  6. match line with
  7. | None -> inp
  8. | Some x -> one_string (inp ^ x)
  9. in one_string ""
  10. ;;
  11. let repeat_string str n =
  12. String.concat "" (List.init n (fun _ -> str))
  13. ;;
  14. let expand dm =
  15. let rec aux i acc=
  16. if (i >= String.length dm) then
  17. acc
  18. else (if (i == String.length dm -1)
  19. then
  20. let id = string_of_int (i/2) in
  21. let file_size = (int_of_char dm.[i] - int_of_char '0') in
  22. let new_encoding = (repeat_string id file_size) in
  23. (acc ^ new_encoding)
  24. else
  25. let id = string_of_int (i/2) in
  26. let file_size = (int_of_char dm.[i] - int_of_char '0') in
  27. let empty_space = (int_of_char dm.[i+1] - int_of_char '0') in
  28. let new_encoding = (repeat_string id file_size) ^ (String.make empty_space '.') in
  29. aux (i+2) (acc ^ new_encoding))
  30. in
  31. aux 0 String.empty
  32. ;;
  33. let reverse_compact dm=
  34. let rec aux left_most_pos accum =
  35. try
  36. if (left_most_pos < 0) then accum
  37. else
  38. (let nleft_most_pos = search_backward (regexp "[0-9]") dm left_most_pos in
  39. aux (nleft_most_pos-1) (accum^(String.make 1 dm.[nleft_most_pos])))
  40. with Not_found -> accum
  41. in
  42. aux (String.length dm) (String.empty)
  43. ;;
  44. let compact dm rcomp=
  45. let dm_len = (String.length rcomp) in
  46. let rec aux i pos accum =
  47. try
  48. let npos = search_forward (regexp {|\.|}) dm pos in
  49. aux (i+1) (npos+1) (accum ^ (String.sub dm pos (npos - pos)) ^ (String.make 1 rcomp.[i]))
  50. with Not_found -> (String.sub accum 0 dm_len) ^ (String.make 1 '.')
  51. in
  52. aux 0 0 String.empty
  53. ;;
  54. let calculate_checksum dm=
  55. let rec aux id accum =
  56. if (dm.[id] == '.') then accum
  57. else
  58. let block = (int_of_char dm.[id] - int_of_char '0') in
  59. (aux (id+1) ((id * block) + accum))
  60. in
  61. aux 0 0;;
  62. let solve =
  63. let expanded = expand input in
  64. calculate_checksum
  65. (compact expanded (reverse_compact expanded));
  66. ;;
  67. let () =
  68. printf "%s\n" (expand input);
  69. (* printf "%s\n" (reverse_compact (expand input)); *)
  70. (* printf "%s\n" (compact (expand input) (reverse_compact (expand input))); *)
  71. (* printf "Total: %d\n" solve;; *)