a-conjecture-of-mine

An exercise on polyglossy: the same problem solved on multiple languages

commit 19e1ac07e6180cede53110fea0c61e125a961860
parent f75107bb25560e88634360c536e8feee42aa9670
Author: Pablo Escobar Gaviria <gark.garcia@protonmail.com>
Date:   Tue,  4 Feb 2020 22:38:45 -0200

Made the OCaml implementation concurrent.

Unfortunatelly it's broken right now. Probably something to do with the  syncronization and message passing primitives.

Diffstat:
MOCaml/main.ml | 52++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 44 insertions(+), 8 deletions(-)
diff --git a/OCaml/main.ml b/OCaml/main.ml
@@ -7,6 +7,15 @@
 let failure: int = 1;;
 let invalid_input: int = 2;;
 
+type range = 
+    { sums_cache: int array;
+      start: int; 
+      step: int; 
+      stop: int;
+      channel: bool Event.channel 
+    }
+;;
+
 (** Returns the sum of the digits of `n`, where `n` is a positive integer. *) 
 let sum_digits (n: int) : int =
     let rec sum_digits_tail n acc =
@@ -24,17 +33,44 @@ let get_sums (max: int) : int array =
 
 let test (a: int) (b: int) (sums_cache: int array) : bool =
     let sum_digits n = Array.get sums_cache n in
-    0 = (sum_digits (a + b) - sum_digits a - sum_digits b) mod 9
+    0 <> (sum_digits (a + b) - sum_digits a - sum_digits b) mod 9
+;;
+
+let rec listen (c: bool Event.channel) (n: int) : unit =
+    match n with
+    | 0 -> ()
+    | _ when Event.sync (Event.receive c) -> exit failure 
+    | _ -> listen c (n - 1)
+;;
+
+let counterexempl_range (r: range): unit =
+    let send b = let _ = Event.send r.channel b in Thread.exit () 
+    and a = ref r.start in
+    while !a <= r.stop do
+        for b = 0 to !a do
+            if test !a b r.sums_cache then send true 
+        done;
+
+        a := !a + r.step
+    done;
+
+    send false
 ;;
 
 (* TODO: Use concurency. *)
-let counterexempl (max: int) : unit =
+let counterexempl (max: int) (n_threads: int) : unit =
     let sums_cache = get_sums max in
-    for a = 0 to max do 
-        for b = 0 to a do
-            if test a b sums_cache then () else exit failure
-        done
-    done
+    let c = Event.new_channel () in
+    let range_of n = 
+        { sums_cache = sums_cache;
+          start = n; 
+          step = n_threads; 
+          stop = max; 
+          channel = c
+        } in
+    let spawn n = Thread.create counterexempl_range (range_of n)  in
+    let _ = Array.init n_threads spawn in
+    listen c n_threads 
 ;;
 
 let main () =
@@ -42,7 +78,7 @@ let main () =
         let max_str = Sys.argv.(1) in
 
         match int_of_string_opt max_str with
-        | Some max when max > 0 -> counterexempl max 
+        | Some max when max > 0 -> counterexempl max 2
         | _ -> exit invalid_input
     else
         exit invalid_input