let canonical s = let chars = Array.make 26 0 in for i = 0 to String.length s - 1 do let k = Char.code s.[i] - Char.code 'a' in if k >= 0 && k < 26 then chars.(k) <- chars.(k) + 1 done; let buf = Buffer.create 26 in for i = 0 to 25 do for _ = 1 to chars.(i) do Buffer.add_string buf (String.make 1 (Char.chr (i + Char.code 'a'))) done done; Buffer.contents buf let group_anagrams xs = let h = Hashtbl.create 8 in List.iter (fun s -> let k = canonical s in let cur = match Hashtbl.find_opt h k with | Some xs -> xs | None -> [] in Hashtbl.replace h k (s :: cur) ) xs; Hashtbl.length h ;; group_anagrams ["eat"; "tea"; "tan"; "ate"; "nat"; "bat"]