My yearly advent-of-code solutions
1let filename = "./day_02_input.txt"
2let try_read ic = try Some (input_line ic) with End_of_file -> None
3
4let is_values_safe a b direction =
5 match direction with
6 | "up" -> a < b && abs (a - b) < 4
7 | "down" -> a > b && abs (a - b) < 4
8 | _ -> false
9
10let direction a b = if a < b then "up" else "down"
11
12let is_line_safe list =
13 let a, b = (List.hd list, List.tl list |> List.hd) in
14 let direction = direction a b in
15 List.fold_left
16 (fun (acc, prev) x ->
17 if prev > -1 then (acc && is_values_safe prev x direction, x) else (acc, x))
18 (true, -1) list
19 |> fst
20
21let is_line_safe_part_2 list =
22 List.mapi
23 (fun i _ -> List.filteri (fun j _ -> j <> i) list |> is_line_safe)
24 list
25 |> List.exists (fun x -> x)
26
27let calculate_safe_score ic is_line_safe =
28 let rec calculate acc =
29 match try_read ic with
30 | Some line -> (
31 match
32 is_line_safe (String.split_on_char ' ' line |> List.map int_of_string)
33 with
34 | true -> calculate (acc + 1)
35 | false -> calculate acc)
36 | None ->
37 close_in ic;
38 acc
39 in
40 calculate 0
41
42let () =
43 let ic = open_in filename in
44 calculate_safe_score ic is_line_safe
45 |> Printf.sprintf "Safe %d" |> print_endline;
46
47 let ic = open_in filename in
48 calculate_safe_score ic is_line_safe_part_2
49 |> Printf.sprintf "Part 2 Safe %d"
50 |> print_endline