lib.ml 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. (* open Base *)
  2. open Core
  3. module PairCmp = struct
  4. module T = struct
  5. type t = int * int
  6. let compare x y = Tuple2.compare ~cmp1:Int.compare ~cmp2:Int.compare x y
  7. let sexp_of_t = Tuple2.sexp_of_t Int.sexp_of_t Int.sexp_of_t
  8. let t_of_sexp = Tuple2.t_of_sexp Int.t_of_sexp Int.t_of_sexp
  9. end
  10. include T
  11. include Comparable.Make(T)
  12. end
  13. let all_slopes = [
  14. (1, 1);
  15. (3, 1);
  16. (5, 1);
  17. (7, 1);
  18. (1, 2);
  19. ]
  20. type map = {
  21. height: int;
  22. width: int;
  23. content: (PairCmp.t, bool, PairCmp.comparator_witness) Map.t;
  24. }
  25. let parse_map str =
  26. let lines = String.split str ~on:'\n' in
  27. let assoc =
  28. List.mapi lines ~f:(fun row line ->
  29. List.mapi (String.to_list line) ~f:(fun col value ->
  30. ((col, row), phys_equal value '#'))) in
  31. {
  32. height = List.length assoc;
  33. width = List.length (List.nth_exn assoc 0);
  34. content = Map.of_alist_exn (module PairCmp) (List.join assoc);
  35. }
  36. let count_trees_in_slope map (dx, dy) =
  37. let rec helper x y =
  38. if y >= map.height then 0
  39. else if x >= map.width then helper (x - map.width) y
  40. else if Map.find_exn map.content (x, y) then 1 + helper (x + dx) (y + dy)
  41. else helper (x + dx) (y + dy)
  42. in helper 0 0