let split s = let half = (String.length s) / 2 in (String.sub s 0 half, String.sub s half half) let find_duplicates s1 s2 = String.to_seq s1 |> Seq.filter (fun c -> String.contains s2 c) |> Seq.fold_left (fun acc c -> if String.contains acc c then acc else acc ^ String.make 1 c) "" let priority item = let num = int_of_char item in if num > 96 then num - 96 else num - 38 let find_duplicates3 s1 s2 s3 = find_duplicates s1 (find_duplicates s2 s3) let get_duplicate dup = try Some(String.get dup 0 |> priority) with Failure _ -> None open Utils let part1 l = l |> List.filter_map (fun s -> split s |> uncurry find_duplicates |> get_duplicate) |> List.fold_left (+) 0 ;; let triplets l = let rec aux res = function | [] | [_] | _ :: _ :: []-> res | elv1 :: elv2 :: elv3 :: tail -> aux ((elv1, elv2, elv3) :: res) tail in aux [] l ;; let part2 l = l |> triplets |> List.filter_map (fun triplet -> (uncurry3 find_duplicates3) triplet |> get_duplicate) |> List.fold_left (+) 0 ;; "\n1: " ^ string_of_int (read_file "bin/d3/input.txt" |> part1) ^ "\n2: " ^ string_of_int (read_file "bin/d3/input.txt" |> part2) |> print_endline