diff options
| -rw-r--r-- | challenge-242/bruce-gray/fsharp/ch-1.fsx | 29 | ||||
| -rw-r--r-- | challenge-242/bruce-gray/fsharp/ch-1_scary.fsx | 28 | ||||
| -rw-r--r-- | challenge-242/bruce-gray/fsharp/ch-2.fsx | 32 | ||||
| -rw-r--r-- | challenge-242/bruce-gray/raku/ch-1.raku | 15 | ||||
| -rw-r--r-- | challenge-242/bruce-gray/raku/ch-2.raku | 23 |
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>; +} |
