01.sml 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. fun read file =
  2. let
  3. val inStream = TextIO.openIn file
  4. in
  5. (* TextIO.inputAll returns a TextIO.vector, which is a string. *)
  6. TextIO.inputAll inStream
  7. end;
  8. val newline_tokenizer = String.tokens (fn c => c = #"\n");
  9. val space_tokenizer = String.tokens (fn c => c = #" ");
  10. datatype HorizontalChange = HorizontalChange of int;
  11. datatype DepthChange = DepthChange of int;
  12. type change = HorizontalChange * DepthChange;
  13. fun direction_to_factor dir =
  14. case dir of
  15. "forward" => 1
  16. | "backward" => ~1
  17. | "up" => ~1
  18. | "down" => 1
  19. | _ => raise Fail "unrecognized direction";
  20. fun calc_change line =
  21. let
  22. val (dir::len_as_str::_) = space_tokenizer line;
  23. val len = case Int.fromString len_as_str of
  24. SOME number => number
  25. | NONE => raise Fail "encountered a non-int string";
  26. val dir_factor = direction_to_factor dir;
  27. in
  28. case dir of
  29. "forward" => (HorizontalChange (dir_factor * len), DepthChange 0)
  30. | "backward" => (HorizontalChange (dir_factor * len), DepthChange 0)
  31. | "up" => (HorizontalChange 0, DepthChange (dir_factor * len))
  32. | "down" => (HorizontalChange 0, DepthChange (dir_factor * len))
  33. | _ => raise Fail "unrecognized direction"
  34. end;
  35. fun plus_changes (change1, change2) =
  36. let
  37. val (HorizontalChange h1, DepthChange d1) = change1;
  38. val (HorizontalChange h2, DepthChange d2) = change2;
  39. in
  40. (HorizontalChange (h1 + h2), DepthChange (d1 + d2))
  41. end;
  42. val initial_change = (HorizontalChange 0, DepthChange 0): change;
  43. val str = read "input";
  44. val lines = newline_tokenizer str;
  45. let
  46. val (HorizontalChange h, DepthChange d) =
  47. foldl (fn (line, acc) => plus_changes (acc, (calc_change line)))
  48. initial_change
  49. lines;
  50. val solution = h * d;
  51. in
  52. solution
  53. end;