aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-242/bruce-gray/fsharp/ch-1.fsx29
-rw-r--r--challenge-242/bruce-gray/fsharp/ch-1_scary.fsx28
-rw-r--r--challenge-242/bruce-gray/fsharp/ch-2.fsx32
-rw-r--r--challenge-242/bruce-gray/raku/ch-1.raku15
-rw-r--r--challenge-242/bruce-gray/raku/ch-2.raku23
5 files changed, 127 insertions, 0 deletions
diff --git a/challenge-242/bruce-gray/fsharp/ch-1.fsx b/challenge-242/bruce-gray/fsharp/ch-1.fsx
new file mode 100644
index 0000000000..7e3149a500
--- /dev/null
+++ b/challenge-242/bruce-gray/fsharp/ch-1.fsx
@@ -0,0 +1,29 @@
+// To execute from the command line: `dotnet fsi fsharp/ch-1.fsx`
+
+// See also my alternate phrasing of the same solution: ch-1_scary.fsx
+
+let task1 (ns1: int list, ns2: int list) =
+ let s1 = Set.ofList ns1
+ let s2 = Set.ofList ns2
+
+ let diff (sa: Set<int>) (sb: Set<int>) =
+ Set.difference sa sb |> Set.toList
+
+ ( diff s1 s2 , diff s2 s1 )
+
+// Below this point is test harness and data.
+let mutable test_number = 0
+let is (got: 'a) (expected: 'a) (test_name: string) =
+ test_number <- test_number + 1
+ let ok_msg = if (got = expected) then "ok" else "not ok"
+ printfn $"{ok_msg} {test_number} {test_name}"
+ ()
+
+type TestRecord = { input: list<int> * list<int>; expected: list<int> * list<int> }
+let tests: TestRecord list = [
+ { input = ( [1; 2; 3] , [2; 4; 6] ); expected = ( [1; 3] , [4; 6] ) };
+ { input = ( [1; 2; 3; 3] , [1; 1; 2; 2] ); expected = ( [3; ] , [ ] ) };
+]
+for test in tests do
+ let got = task1 test.input
+ is got test.expected "Task1 example"
diff --git a/challenge-242/bruce-gray/fsharp/ch-1_scary.fsx b/challenge-242/bruce-gray/fsharp/ch-1_scary.fsx
new file mode 100644
index 0000000000..9b0e4a68f1
--- /dev/null
+++ b/challenge-242/bruce-gray/fsharp/ch-1_scary.fsx
@@ -0,0 +1,28 @@
+// For the Halloween season, a scary Haskell-style point-free solution!
+// To execute from the command line: `dotnet fsi fsharp/ch-1_scary.fsx`
+
+let uncurry f (x, y) = f x y
+let mapBoth f (x, y) = f x, f y
+let fwdAndRev f (x, y) = f (x, y) , f (y, x)
+
+let diffs = mapBoth Set.ofList >> uncurry Set.difference >> Set.toList
+let task1 = fwdAndRev diffs
+
+
+// Below this point is test harness and data.
+let mutable test_number = 0
+let is (got: 'a) (expected: 'a) (test_name: string) =
+ test_number <- test_number + 1
+ let ok_msg = if (got = expected) then "ok" else "not ok"
+ printfn $"{ok_msg} {test_number} {test_name}"
+ ()
+
+//type intListPair = list<int> * list<int> // XXX Include? move higher?
+type TestRecord = { input: list<int> * list<int>; expected: list<int> * list<int> }
+let tests: TestRecord list = [
+ { input = ( [1; 2; 3] , [2; 4; 6] ); expected = ( [1; 3] , [4; 6] ) };
+ { input = ( [1; 2; 3; 3] , [1; 1; 2; 2] ); expected = ( [3; ] , [ ] ) };
+]
+for test in tests do
+ let got = task1 test.input
+ is got test.expected "Task1 example"
diff --git a/challenge-242/bruce-gray/fsharp/ch-2.fsx b/challenge-242/bruce-gray/fsharp/ch-2.fsx
new file mode 100644
index 0000000000..22243bb542
--- /dev/null
+++ b/challenge-242/bruce-gray/fsharp/ch-2.fsx
@@ -0,0 +1,32 @@
+// To execute from the command line: `dotnet fsi fsharp/ch-2.fsx`
+
+let task2 ( arr : int array2d ) =
+ let row_count = Array2D.length1 arr
+ let col_count = Array2D.length2 arr
+ let build_it = fun i j -> (arr[i, col_count - 1 - j] + 1) % 2
+ Array2D.init row_count col_count build_it
+
+
+
+// Below this point is test harness and data.
+let mutable test_number = 0
+let is (got: 'a) (expected: 'a) (test_name: string) =
+ test_number <- test_number + 1
+ let ok_msg = if (got = expected) then "ok" else "not ok"
+ printfn $"{ok_msg} {test_number} {test_name}"
+ ()
+
+type TestRecord = { input: int array2d; expected: int array2d }
+let tests = [
+ {
+ input = array2D [[1; 1; 0]; [1; 0; 1]; [0; 0; 0]]
+ expected = array2D [[1; 0; 0]; [0; 1; 0]; [1; 1; 1]]
+ }
+ { input = array2D [[1; 1; 0; 0]; [1; 0; 0; 1]; [0; 1; 1; 1]; [1; 0; 1; 0]]
+ expected = array2D [[1; 1; 0; 0]; [0; 1; 1; 0]; [0; 0; 0; 1]; [1; 0; 1; 0]]
+ }
+]
+
+for test in tests do
+ let got = task2 test.input
+ is got test.expected "Task2 example"
diff --git a/challenge-242/bruce-gray/raku/ch-1.raku b/challenge-242/bruce-gray/raku/ch-1.raku
new file mode 100644
index 0000000000..6765f36bbb
--- /dev/null
+++ b/challenge-242/bruce-gray/raku/ch-1.raku
@@ -0,0 +1,15 @@
+sub task1 ( @ns1, @ns2 ) {
+ return (@ns1, @ns2).permutations.map:
+ *.reduce( &[(-)] ).keys.sort.List;
+}
+
+
+
+my @tests =
+ { in => ( (1, 2, 3) , (2, 4, 6) ), expected => ( (1, 3) , (4, 6) ) },
+ { in => ( (1, 2, 3, 3) , (1, 1, 2, 2) ), expected => ( (3, ) , ( ) ) },
+;
+use Test; plan +@tests;
+for @tests {
+ is-deeply task1(|.<in>), .<expected>;
+}
diff --git a/challenge-242/bruce-gray/raku/ch-2.raku b/challenge-242/bruce-gray/raku/ch-2.raku
new file mode 100644
index 0000000000..4e2f7d49a3
--- /dev/null
+++ b/challenge-242/bruce-gray/raku/ch-2.raku
@@ -0,0 +1,23 @@
+sub flip { +!$^n }
+# sub flip { ($^n + 1) mod 2 } # Different approach
+
+sub task2 (@matrix) {
+ return @matrix.map:
+ *.reverse.map(&flip).List;
+}
+
+
+my @tests =
+ {
+ in => ((1, 1, 0), (1, 0, 1), (0, 0, 0)),
+ expected => ((1, 0, 0), (0, 1, 0), (1, 1, 1)),
+ },
+ {
+ in => ((1, 1, 0, 0), (1, 0, 0, 1), (0, 1, 1, 1), (1, 0, 1, 0)),
+ expected => ((1, 1, 0, 0), (0, 1, 1, 0), (0, 0, 0, 1), (1, 0, 1, 0)),
+ },
+;
+use Test; plan +@tests;
+for @tests {
+ is-deeply task2(.<in>), .<expected>;
+}