aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn <shawnw.mobile@gmail.com>2020-10-06 03:44:34 -0700
committerShawn <shawnw.mobile@gmail.com>2020-10-06 03:44:34 -0700
commit93fd868652256520216fc08c2d6252c6f9f8e016 (patch)
treea85a859f0a8dc0484b1d5ace7ec9f4b01beb9880
parentfb1c8aa62a6ea258f6b0d0198652d3effd889ae5 (diff)
downloadperlweeklychallenge-club-93fd868652256520216fc08c2d6252c6f9f8e016.tar.gz
perlweeklychallenge-club-93fd868652256520216fc08c2d6252c6f9f8e016.tar.bz2
perlweeklychallenge-club-93fd868652256520216fc08c2d6252c6f9f8e016.zip
Challenge 081, both parts in ocaml
-rw-r--r--challenge-081/shawn-wagner/ocaml/Makefile20
-rw-r--r--challenge-081/shawn-wagner/ocaml/ch1.ml34
-rw-r--r--challenge-081/shawn-wagner/ocaml/ch2.ml39
3 files changed, 93 insertions, 0 deletions
diff --git a/challenge-081/shawn-wagner/ocaml/Makefile b/challenge-081/shawn-wagner/ocaml/Makefile
new file mode 100644
index 0000000000..c3a8f32410
--- /dev/null
+++ b/challenge-081/shawn-wagner/ocaml/Makefile
@@ -0,0 +1,20 @@
+.PHONY: all clean opt
+
+all: ch1 ch2
+
+opt: ch1x ch2x
+
+ch1: ch1.ml
+ ocamlc -o ch1 ch1.ml
+
+ch2: ch2.ml
+ ocamlc -o ch2 str.cma ch2.ml
+
+ch1x: ch1.ml
+ ocamlopt -o ch1x ch1.ml
+
+ch2x: ch2.ml
+ ocamlopt -o ch2x str.cmxa ch2.ml
+
+clean:
+ rm -f ch1 ch2 ch1x ch2x *.cmo *.cmi *.cmx *.o
diff --git a/challenge-081/shawn-wagner/ocaml/ch1.ml b/challenge-081/shawn-wagner/ocaml/ch1.ml
new file mode 100644
index 0000000000..71306a0770
--- /dev/null
+++ b/challenge-081/shawn-wagner/ocaml/ch1.ml
@@ -0,0 +1,34 @@
+(* My other solutions use hash tables; let's use a set here instead *)
+module StringSet = Set.Make(String)
+
+let substrings s =
+ let subs = ref StringSet.empty in
+ let len = String.length s in
+ for start = 0 to len - 1 do
+ for slen = 1 to len - start do
+ subs := StringSet.add (String.sub s start slen) !subs
+ done
+ done;
+ !subs
+
+let repeat s n =
+ let len = String.length s in
+ let newlen = len * n in
+ String.init newlen (function i -> String.get s (i mod len))
+
+(* And a non-regular epxression test *)
+let ismadeof s sub =
+ let reps = (String.length s) / (String.length sub) in
+ String.equal (repeat sub reps) s
+
+let task1 a b =
+ let subs = StringSet.inter (substrings a) (substrings b) in
+ let f sub =
+ if ismadeof a sub && ismadeof b sub then
+ Printf.printf "%s " sub in
+ StringSet.iter f subs;
+ print_newline ()
+
+let _ =
+ task1 "abcdabcd" "abcdabcdabcdabcd";
+ task1 "aaa" "a"
diff --git a/challenge-081/shawn-wagner/ocaml/ch2.ml b/challenge-081/shawn-wagner/ocaml/ch2.ml
new file mode 100644
index 0000000000..34a9131687
--- /dev/null
+++ b/challenge-081/shawn-wagner/ocaml/ch2.ml
@@ -0,0 +1,39 @@
+let find_def tbl key def =
+ match Hashtbl.find_opt tbl key with
+ | Some x -> x
+ | None -> def
+
+let re = Str.regexp "[.\"(),]\\|--\\|'s"
+
+let strip_special word = Str.global_replace re "" word
+
+let task2 filename =
+ let ib = Scanf.Scanning.open_in filename in
+ let words = Hashtbl.create 100 in
+ let add_word word =
+ if word <> "" then begin
+ let word = strip_special word in
+ Hashtbl.replace words word ((find_def words word 0) + 1);
+ true
+ end else
+ false in
+ while Scanf.bscanf ib " %s" add_word do
+ ()
+ done;
+ Scanf.Scanning.close_in ib;
+ let maxfreq = ref 0 in
+ let frequencies = Hashtbl.create (Hashtbl.length words) in
+ Hashtbl.iter (fun w count -> Hashtbl.add frequencies count w;
+ maxfreq := max count !maxfreq) words;
+ for count = 1 to !maxfreq do
+ if Hashtbl.mem frequencies count then begin
+ Printf.printf "%d " count;
+ List.iter (function word -> Printf.printf "%s " word)
+ (List.sort String.compare (Hashtbl.find_all frequencies count));
+ print_newline()
+ end
+ done
+
+let _ =
+ task2 "input"
+