summaryrefslogtreecommitdiff
path: root/ocaml/lib/year2025/day01/part02/turner.ml
blob: 7477093719031aaf11618cb38ebd430444ba227e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
open Dial

module Turner : sig
  val turn : Dial.t -> int -> Dial.direction -> Dial.t * int
  (** [turn dial direction] is the new state of the dial after turning [direction] on [dial] *)
end = struct
  (** [turn dial direction] is the new state of the dial after turning [direction] on [dial].
      Raises: [dial_out_of_range] if the dial is moved to an invalid state. *)
  let rec turn dial zero_count direction =
    let open Dial in
    match direction with
    | Left 0 ->
        (dial, zero_count)
    | Left n ->
        let dial' = prev dial in
        let zero_count' =
          if Dial.is_zero dial' then zero_count + 1 else zero_count
        in
        turn dial' zero_count' (Left (n - 1))
    | Right 0 ->
        (dial, zero_count)
    | Right n ->
        let dial' = next dial in
        let zero_count' =
          if Dial.is_zero dial' then zero_count + 1 else zero_count
        in
        turn dial' zero_count' (Right (n - 1))
end