fork download
  1.  
  2. let rec take_while f xs =
  3. match xs with
  4. | [] -> []
  5. | x :: rest -> if f x
  6. then x :: take_while f rest
  7. else []
  8.  
  9. let rec drop_while f xs =
  10. match xs with
  11. | [] -> []
  12. | x :: rest -> if f x
  13. then drop_while f rest
  14. else xs
  15.  
  16. let span f xs = (take_while f xs, drop_while f xs)
  17.  
  18. let string_to_char_list s =
  19. let rec string_to_char_list_impl i l =
  20. if i < 0
  21. then l
  22. else string_to_char_list_impl (i - 1) (s.[i] :: l) in
  23. string_to_char_list_impl (String.length s - 1) []
  24.  
  25. let char_list_to_string cs =
  26. String.concat "" (List.map (fun x -> String.make 1 x) cs)
  27.  
  28. let next_permutation word =
  29. let rec next_permutation_impl char_list =
  30. match char_list with
  31. | x0 :: rest0 ->
  32. (match next_permutation_impl rest0 with
  33. | (true, rest1) -> (true, x0 :: rest1)
  34. | (false, rest1) ->
  35. (match rest1 with
  36. | [] -> (false, x0 :: rest1)
  37. | x1 :: _ ->
  38. if x0 < x1
  39. then
  40. let (left, right) = span (fun x -> x > x0) rest1 in
  41. let chunk =
  42. (match (List.rev left, List.rev right) with
  43. | ([], _) -> raise (Failure "Chpoke")
  44. | (l :: revLeft, revRight) -> List.concat [[l]; revRight; [x0]; revLeft])
  45. in (match chunk with
  46. | (x2 :: rest2) -> (true, x2 :: rest2)
  47. | [] -> raise (Failure "Chpoke"))
  48. else (false, x0 :: rest1)))
  49. | [] -> (false, [])
  50. in
  51. let char_list = string_to_char_list word in
  52. match next_permutation_impl char_list with
  53. | (true, result) -> Some (char_list_to_string result)
  54. | _ -> None
  55.  
Success #stdin #stdout 0s 4212KB
stdin
Standard input is empty
stdout
Standard output is empty