aboutsummaryrefslogtreecommitdiff
path: root/2024/day_02.ml
blob: 2532ad8e4acd47acff89379abdd3430018412db5 (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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
let filename = "./day_02_input.txt"
let try_read ic = try Some (input_line ic) with End_of_file -> None

let is_values_safe a b direction =
  match direction with
  | "up" -> a < b && abs (a - b) < 4
  | "down" -> a > b && abs (a - b) < 4
  | _ -> false

let direction a b = if a < b then "up" else "down"

let is_line_safe list =
  let a, b = (List.hd list, List.tl list |> List.hd) in
  let direction = direction a b in
  List.fold_left
    (fun (acc, prev) x ->
      if prev > -1 then (acc && is_values_safe prev x direction, x) else (acc, x))
    (true, -1) list
  |> fst

let is_line_safe_part_2 list =
  List.mapi
    (fun i _ -> List.filteri (fun j _ -> j <> i) list |> is_line_safe)
    list
  |> List.exists (fun x -> x)

let calculate_safe_score ic is_line_safe =
  let rec calculate acc =
    match try_read ic with
    | Some line -> (
        match
          is_line_safe (String.split_on_char ' ' line |> List.map int_of_string)
        with
        | true -> calculate (acc + 1)
        | false -> calculate acc)
    | None ->
        close_in ic;
        acc
  in
  calculate 0

let () =
  let ic = open_in filename in
  calculate_safe_score ic is_line_safe
  |> Printf.sprintf "Safe %d" |> print_endline;

  let ic = open_in filename in
  calculate_safe_score ic is_line_safe_part_2
  |> Printf.sprintf "Part 2 Safe %d"
  |> print_endline