aboutsummaryrefslogtreecommitdiff
path: root/motus/lib
diff options
context:
space:
mode:
authorSébastien Dailly <sebastien@dailly.me>2022-02-11 09:22:18 +0100
committerSébastien Dailly <sebastien@dailly.me>2022-02-11 09:28:26 +0100
commit82bb54622a47bb092094c8efab8200b12817c5b4 (patch)
treef160d66a09d2bf0e8f2bdbef5dbec17126ecd4a1 /motus/lib
parentd20d14b4f4a903ef9aea4c01dd46fab5ecbab6ae (diff)
Hide structure in motus solver
Diffstat (limited to 'motus/lib')
-rw-r--r--motus/lib/persistence.ml46
-rw-r--r--motus/lib/persistence.mli24
2 files changed, 57 insertions, 13 deletions
diff --git a/motus/lib/persistence.ml b/motus/lib/persistence.ml
index 1bc20ad..6116653 100644
--- a/motus/lib/persistence.ml
+++ b/motus/lib/persistence.ml
@@ -1,3 +1,7 @@
+open StdLabels
+
+let () = Random.self_init ()
+
type t =
{ number : int
; element : string list
@@ -12,7 +16,7 @@ let extract_freq : t -> (char * int) list =
let number_2 = data.number / 2 in
Hashtbl.fold (fun k v acc -> (k, abs (v - number_2)) :: acc) data.freq []
(* Sort the list for a pretty printing *)
- |> List.sort (fun v1 v2 -> snd v1 - snd v2)
+ |> List.sort ~cmp:(fun v1 v2 -> snd v1 - snd v2)
let update_freq : (char, int) Hashtbl.t -> char -> unit =
@@ -24,15 +28,15 @@ let update_freq : (char, int) Hashtbl.t -> char -> unit =
let add_word : Criteria.t list -> t -> string -> t =
fun filters data word ->
- match List.for_all (Criteria.check_filter word) filters with
+ match List.for_all ~f:(Criteria.check_filter word) filters with
| true ->
let len = String.length word in
let chars =
- List.init len (fun n -> String.get word n)
- |> List.sort_uniq Char.compare
+ List.init ~len ~f:(fun n -> String.get word n)
+ |> List.sort_uniq ~cmp:Char.compare
in
- List.iter (update_freq data.freq) chars;
+ List.iter ~f:(update_freq data.freq) chars;
{ data with number = data.number + 1; element = word :: data.element }
| false -> data
@@ -45,12 +49,12 @@ present many times, we consider that succeding letters does not give any more
informations (do not consider the position here) *)
let pick_next_word : t -> (char * int) list -> string * int =
fun data scores ->
- let p' : (string * int) option -> string -> (string * int) option =
+ let p' : (string list * int) option -> string -> (string list * int) option =
fun prec word ->
(* evaluate the score for this word *)
let _, eval =
String.fold_left
- (fun (scores, score) c ->
+ ~f:(fun (scores, score) c ->
match List.assoc_opt c scores with
| None ->
(* if the character has no score associated, we consider that it
@@ -59,17 +63,33 @@ let pick_next_word : t -> (char * int) list -> string * int =
(scores, score + (data.number / 2))
| Some v ->
let new_scores =
- List.filter (fun (c', _) -> not (Char.equal c c')) scores
+ List.filter ~f:(fun (c', _) -> not (Char.equal c c')) scores
in
(new_scores, score + v) )
- (scores, 0)
+ ~init:(scores, 0)
word
in
match prec with
- | None -> Some (word, eval)
- | Some (_, prec_score) when eval < prec_score -> Some (word, eval)
+ | None -> Some ([ word ], eval)
+ | Some (_, prec_score) when eval < prec_score -> Some ([ word ], eval)
+ | Some (w, prec_score) when eval = prec_score -> Some (word :: w, eval)
| _ -> prec
in
- match List.fold_left p' None data.element with
+ match List.fold_left ~f:p' ~init:None data.element with
| None -> ("", 0)
- | Some r -> r
+ | Some (words, score) ->
+ (* Pick a reandom word from the list *)
+ let elements = List.length words in
+ let number = Random.int elements in
+ (List.nth words number, score)
+
+
+let remove_word : t -> string -> t =
+ fun t word ->
+ let element = List.filter ~f:(fun w -> not (String.equal w word)) t.element in
+ { t with element; number = t.number - 1 }
+
+
+let words : t -> string list = fun { element; _ } -> element
+
+let list_size : t -> int = fun { number; _ } -> number
diff --git a/motus/lib/persistence.mli b/motus/lib/persistence.mli
new file mode 100644
index 0000000..f5625e4
--- /dev/null
+++ b/motus/lib/persistence.mli
@@ -0,0 +1,24 @@
+type t
+
+val words : t -> string list
+
+val list_size : t -> int
+(** Number of words in the list *)
+
+val empty_data : unit -> t
+
+val extract_freq : t -> (char * int) list
+(** Evaluate the score for each char (lower is better) *)
+
+val add_word : Criteria.t list -> t -> string -> t
+(** Add a new word in the list. Check are made against the differents criteria in order to ensure that the word is valid *)
+
+val pick_next_word : t -> (char * int) list -> string * int
+(** Get the word which with the most information in it.
+
+The information is the score given to each character, representing each
+frequency in the whole word list (lower is better). If the same letter is
+present many times, we consider that succeding letters does not give any more
+informations (do not consider the position here) *)
+
+val remove_word : t -> string -> t