58 lines
1.7 KiB
OCaml
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
|