clean code

This commit is contained in:
zapashcanon 2020-08-02 03:15:12 +02:00
parent d8211a1dc4
commit 952b5f1b2f
Signed by: zapashcanon
GPG Key ID: 8981C3C62D1D28F1
3 changed files with 50 additions and 52 deletions

View File

@ -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)

View File

@ -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

View File

@ -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...@." ;