From 952b5f1b2fb9c9e71d77dd0675dbd296c020b2c1 Mon Sep 17 00:00:00 2001 From: zapashcanon Date: Sun, 2 Aug 2020 03:15:12 +0200 Subject: [PATCH] clean code --- example/random_text.ml | 4 ++- src/omg.ml | 80 ++++++++++++++++++++---------------------- test/test.ml | 18 +++++----- 3 files changed, 50 insertions(+), 52 deletions(-) diff --git a/example/random_text.ml b/example/random_text.ml index e4bf823..841ac11 100644 --- a/example/random_text.ml +++ b/example/random_text.ml @@ -27,7 +27,9 @@ let _ = with End_of_file -> close_in chan ) ; let lines = List.rev !lines in let generator = Omg.init () in - List.iter (fun el -> Omg.feed generator el) lines ; + let generator = + List.fold_left (fun generator el -> Omg.feed generator el) generator lines + in for _ = 0 to 30 do Format.fprintf Format.std_formatter "GEN: %s@." (Omg.generate_markov_text generator 50 (None, None) false) diff --git a/src/omg.ml b/src/omg.ml index 563fcc3..f697f9e 100644 --- a/src/omg.ml +++ b/src/omg.ml @@ -1,18 +1,20 @@ -let _ = Random.self_init () +let () = Random.self_init () type generator = { forward_cache: (string * string, (string, int) Hashtbl.t) Hashtbl.t ; backward_cache: (string * string, (string, int) Hashtbl.t) Hashtbl.t ; words: (int, string) Hashtbl.t - ; last_two_words: (string * string) ref } + ; last_two_words: string * string } + +let list_random_el l = List.nth l (Random.int (List.length l)) let add_word generator w = - generator.last_two_words := (snd !(generator.last_two_words), w) ; let n = Hashtbl.length generator.words in - Hashtbl.add generator.words n w + Hashtbl.add generator.words n w ; + {generator with last_two_words= (snd generator.last_two_words, w)} let get_last_two_words generator = - match !(generator.last_two_words) with + match generator.last_two_words with | "", "" -> [] | x, "" | "", x -> @@ -25,9 +27,9 @@ let init () = { forward_cache= Hashtbl.create 4096 ; backward_cache= Hashtbl.create 4096 ; words= Hashtbl.create 4096 - ; last_two_words= ref ("", "") } + ; last_two_words= ("", "") } in - add_word gen "\n" ; gen + add_word gen "\n" let triples = function | w1 :: w2 :: s -> @@ -57,43 +59,44 @@ let feed generator msg = let splitted = splitted @ ["\n"] in let triples = triples (get_last_two_words generator @ splitted) in List.iter - (fun (w1, w2, w3) -> add_key generator.forward_cache (w1, w2) w3) + (fun (w1, w2, w3) -> + add_key generator.forward_cache (w1, w2) w3 ; + add_key generator.backward_cache (w3, w2) w1) triples ; - List.iter - (fun (w1, w2, w3) -> add_key generator.backward_cache (w3, w2) w1) - triples ; - List.iter (fun el -> add_word generator el) splitted + List.fold_left (fun generator el -> add_word generator el) generator splitted let select_seed generator seed_word backward = let dir = if backward then -1 else 1 in match seed_word with | None -> - let seed_word = ref "\n" in - let next_word = ref "\n" in - while !seed_word = "\n" || !next_word = "\n" do - let seed = 1 + Random.int (Hashtbl.length generator.words - 2) in - seed_word := Hashtbl.find generator.words seed ; - next_word := Hashtbl.find generator.words (seed + dir) - done ; - (!seed_word, !next_word) + let rec loop = function + | "\n", _ | _, "\n" -> + let seed = + if backward then + 1 + Random.int (Hashtbl.length generator.words - 1) + else Random.int (Hashtbl.length generator.words - 1) + in + loop + ( Hashtbl.find generator.words seed + , Hashtbl.find generator.words (seed + dir) ) + | seed_word, next_word -> + (seed_word, next_word) + in + loop ("\n", "\n") | Some w -> let possible_indexes = Hashtbl.fold (fun k v acc -> if v = w then k :: acc else acc) generator.words [] in - if possible_indexes = [] then failwith "select_seed" ; - let index = Random.int (List.length possible_indexes) in - let index = List.nth possible_indexes index in - (w, Hashtbl.find generator.words (index + dir)) + let index = list_random_el possible_indexes + dir in + (w, Hashtbl.find generator.words index) let generate_markov_text generator max_size seed backward = let seed_word, next_word = match seed with - | None, None -> - select_seed generator None backward - | Some x, None | None, Some x -> - select_seed generator (Some x) backward + | None, x | x, None -> + select_seed generator x backward | Some x, Some y -> (x, y) in @@ -113,11 +116,7 @@ let generate_markov_text generator max_size seed backward = for _ = 0 to max_size do gen_words := !w1 :: !gen_words ; let tbl = - match Hashtbl.find cache (!w1, !w2) with - | exception Not_found -> - raise Stop - | tbl -> - tbl + try Hashtbl.find cache (!w1, !w2) with Not_found -> raise Stop in let cache_n = Hashtbl.fold (fun _ v acc -> acc + v) tbl 0 in let i = if cache_n = 0 then 0 else Random.int cache_n in @@ -139,16 +138,13 @@ let generate_markov_text generator max_size seed backward = w2 := new_word done with Stop -> () ) ; - if not (!w2 = "\n") then gen_words := !w2 :: !gen_words ; - let gen_words = !gen_words in - let gen_words = List.filter (fun el -> not (el = "\n")) gen_words in + if !w2 <> "\n" then gen_words := !w2 :: !gen_words ; + let gen_words = List.filter (fun el -> el <> "\n") !gen_words in let buff = Buffer.create 512 in - ( match if not backward then List.rev gen_words else gen_words with - | [x] -> - Buffer.add_string buff x + ( match if backward then gen_words else List.rev gen_words with + | [] -> + () | x :: s -> Buffer.add_string buff x ; - List.iter (fun el -> Buffer.add_string buff (" " ^ el)) s - | [] -> - () ) ; + List.iter (fun el -> Buffer.add_string buff (" " ^ el)) s ) ; Buffer.contents buff diff --git a/test/test.ml b/test/test.ml index a2380a4..27387b4 100644 --- a/test/test.ml +++ b/test/test.ml @@ -9,14 +9,14 @@ let test_forward () = let wanted = ["foo bar baz qux"; "bar baz qux"; "baz qux"] in for _ = 1 to 1000 do let generator = Omg.init () in - Omg.feed generator source ; + let generator = Omg.feed generator source in let generated = Omg.generate_markov_text generator 30 (None, None) false in assert (List.mem generated wanted) done ; let seen = List.map (fun el -> (el, ref false)) wanted in for _ = 1 to 1000 do let generator = Omg.init () in - Omg.feed generator source ; + let generator = Omg.feed generator source in let generated = Omg.generate_markov_text generator 30 (None, None) false in List.iter (fun (el, seen) -> if el = generated then seen := true) seen done ; @@ -29,14 +29,14 @@ let test_backward () = let wanted = ["foo bar baz qux"; "foo bar baz"; "foo bar"] in for _ = 1 to 1000 do let generator = Omg.init () in - Omg.feed generator source ; + let generator = Omg.feed generator source in let generated = Omg.generate_markov_text generator 30 (None, None) true in assert (List.mem generated wanted) done ; let seen = List.map (fun el -> (el, ref false)) wanted in for _ = 1 to 1000 do let generator = Omg.init () in - Omg.feed generator source ; + let generator = Omg.feed generator source in let generated = Omg.generate_markov_text generator 30 (None, None) true in List.iter (fun (el, seen) -> if el = generated then seen := true) seen done ; @@ -49,7 +49,7 @@ let test_force_seed_forward () = let wanted = "bar baz qux" in for _ = 1 to 1000 do let generator = Omg.init () in - Omg.feed generator source ; + let generator = Omg.feed generator source in let generated = Omg.generate_markov_text generator 30 (Some "bar", None) false in @@ -59,7 +59,7 @@ let test_force_seed_forward () = done ; for _ = 1 to 1000 do let generator = Omg.init () in - Omg.feed generator source ; + let generator = Omg.feed generator source in let generated = Omg.generate_markov_text generator 30 (Some "bar", Some "baz") false in @@ -72,7 +72,7 @@ let test_force_seed_backward () = let wanted = "foo bar" in for _ = 1 to 1000 do let generator = Omg.init () in - Omg.feed generator source ; + let generator = Omg.feed generator source in let generated = Omg.generate_markov_text generator 30 (Some "bar", None) true in @@ -82,7 +82,7 @@ let test_force_seed_backward () = done ; for _ = 1 to 1000 do let generator = Omg.init () in - Omg.feed generator source ; + let generator = Omg.feed generator source in let generated = Omg.generate_markov_text generator 30 (Some "bar", Some "foo") true in @@ -91,7 +91,7 @@ let test_force_seed_backward () = (Format.sprintf "generated = #%s# and wanted = #%s#@." generated wanted) done -let _ = +let () = Format.printf "testing triples...@." ; test_triples () ; Format.printf "testing forward...@." ;