1
0
Fork 0
advent-of-code-2022/ocaml/3.ml

58 lines
1.7 KiB
OCaml

#use "lib/utils.ml" ;;
let priority_of_item c =
(* ASCII lower case is 97-122, upper case is 65-90 *)
(* Lower case start at 1, upper case at 27 *)
let code = Char.code c in
if code > Char.code 'Z'
then code - (Char.code 'a') + 1
else code - (Char.code 'A') + 27
in
let sum_of_priorities fn str =
let chars = List.sort_uniq compare (list_of_chars str) in
List.fold_left fn 0 chars
in
let sum_rucksack_priorities lines =
let rucksack_priority str =
let len2 = (String.length str)/2 in
let comp1 = String.sub str 0 len2 in
let comp2 = String.sub str len2 len2 in
let char_priority agg c =
if String.contains comp2 c
then (agg + priority_of_item c)
else agg
in
sum_of_priorities char_priority comp1
in
List.fold_left (+) 0 (List.map rucksack_priority lines)
in
let rec sum_badge_priorities sum lines =
let common_badge_priority str1 str2 str3 =
let char_priority agg c =
if String.contains str2 c && String.contains str3 c
then (agg + priority_of_item c)
else agg
in
sum_of_priorities char_priority str1
in
match lines with
| [] -> sum
| hd1 :: tl1 -> match tl1 with
| [] -> failwith "number of rows must be divisible by 3"
| hd2 :: tl2 -> match tl2 with
| [] -> failwith "number of rows must be divisible by 3"
| hd3 :: tl3 -> sum_badge_priorities (sum + common_badge_priority hd1 hd2 hd3) tl3
in
let contents = read_file "inputs/3.txt" in
let lines = String.split_on_char '\n' contents
|> List.filter (fun l -> String.trim l <> "")
in
let sum1 = sum_rucksack_priorities lines in
let sum2 = sum_badge_priorities 0 lines in
Printf.printf "Part 1: %d\n" sum1;
Printf.printf "Part 2: %d\n" sum2