52 lines
1.3 KiB
OCaml
52 lines
1.3 KiB
OCaml
let input_line_opt ic =
|
|
try Some(input_line ic)
|
|
with End_of_file -> None
|
|
|
|
(* load each line in a list *)
|
|
let read_lines ic =
|
|
let rec aux acc =
|
|
match input_line_opt ic with
|
|
| Some line -> aux (line :: acc)
|
|
| None -> (List.rev acc)
|
|
in
|
|
aux []
|
|
|
|
let char_list_of_string str =
|
|
let lst = ref [] in
|
|
String.iter (fun c -> lst := c :: !lst) str;
|
|
(List.rev !lst)
|
|
|
|
let is_ordered word =
|
|
let rec aux = function
|
|
| c1::c2::tl ->
|
|
if c1 <= c2
|
|
then aux (c2::tl)
|
|
else false
|
|
| c::[] -> true
|
|
| [] -> true (* should only occur with an empty string *)
|
|
in
|
|
aux (char_list_of_string word)
|
|
|
|
let longest_words words =
|
|
let res, _ =
|
|
List.fold_left
|
|
(fun (lst, n) word ->
|
|
let len = String.length word in
|
|
let comp = compare len n in
|
|
match lst, comp with
|
|
| lst, 0 -> ((word::lst), n) (* len = n *)
|
|
| lst, -1 -> (lst, n) (* len < n *)
|
|
| _, 1 -> ([word], len) (* len > n *)
|
|
| _ -> assert false
|
|
)
|
|
([""], 0) words
|
|
in
|
|
(List.rev res)
|
|
|
|
let () =
|
|
let ic = open_in "unixdict.txt" in
|
|
let words = read_lines ic in
|
|
let lower_words = List.map String.lowercase words in
|
|
let ordered_words = List.filter is_ordered lower_words in
|
|
let longest_ordered_words = longest_words ordered_words in
|
|
List.iter print_endline longest_ordered_words
|