aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Bell_West <roger@firedrake.org>2024-07-13 09:55:33 +0100
committerRoger Bell_West <roger@firedrake.org>2024-07-13 09:55:33 +0100
commit9bda4e96262f0f0ce16695a366cb0ff860848150 (patch)
treecaacf45afd73704c2815563fd30faee9209ec254
parentbf4eb71a4e5ef70445e3319aba7e9666235a1ecf (diff)
downloadperlweeklychallenge-club-9bda4e96262f0f0ce16695a366cb0ff860848150.tar.gz
perlweeklychallenge-club-9bda4e96262f0f0ce16695a366cb0ff860848150.tar.bz2
perlweeklychallenge-club-9bda4e96262f0f0ce16695a366cb0ff860848150.zip
RogerBW solutions for challenge no. 277
-rwxr-xr-xchallenge-277/roger-bell-west/perl/ch-1.pl19
-rwxr-xr-xchallenge-277/roger-bell-west/perl/ch-2.pl25
-rw-r--r--challenge-277/roger-bell-west/postscript/ch-1.ps96
-rw-r--r--challenge-277/roger-bell-west/postscript/ch-2.ps219
-rwxr-xr-xchallenge-277/roger-bell-west/raku/ch-1.p619
-rwxr-xr-xchallenge-277/roger-bell-west/raku/ch-2.p613
-rwxr-xr-xchallenge-277/roger-bell-west/rust/ch-1.rs42
-rwxr-xr-xchallenge-277/roger-bell-west/rust/ch-2.rs23
-rw-r--r--challenge-277/roger-bell-west/tests.json40
9 files changed, 496 insertions, 0 deletions
diff --git a/challenge-277/roger-bell-west/perl/ch-1.pl b/challenge-277/roger-bell-west/perl/ch-1.pl
new file mode 100755
index 0000000000..9d44dd5a1c
--- /dev/null
+++ b/challenge-277/roger-bell-west/perl/ch-1.pl
@@ -0,0 +1,19 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 3;
+
+is(countcommon(['Perl', 'is', 'my', 'friend'], ['Perl', 'and', 'Raku', 'are', 'friend']), 2, 'example 1');
+is(countcommon(['Perl', 'and', 'Python', 'are', 'very', 'similar'], ['Python', 'is', 'top', 'in', 'guest', 'languages']), 1, 'example 2');
+is(countcommon(['Perl', 'is', 'imperative', 'Lisp', 'is', 'functional'], ['Crystal', 'is', 'similar', 'to', 'Ruby']), 0, 'example 3');
+
+sub countcommon($a, $b) {
+ my %ac;
+ map {$ac{$_}++} @{$a};
+ my %bc;
+ map {$bc{$_}++} @{$b};
+ return scalar grep {$ac{$_} == 1 && exists $bc{$_} && $bc{$_} == 1} keys %ac;
+}
diff --git a/challenge-277/roger-bell-west/perl/ch-2.pl b/challenge-277/roger-bell-west/perl/ch-2.pl
new file mode 100755
index 0000000000..45bf28199f
--- /dev/null
+++ b/challenge-277/roger-bell-west/perl/ch-2.pl
@@ -0,0 +1,25 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 2;
+
+is(strongpair([1, 2, 3, 4, 5]), 4, 'example 1');
+is(strongpair([5, 7, 1, 7]), 1, 'example 2');
+
+use Algorithm::Combinatorics qw(combinations);
+use List::Util qw(min);
+
+sub strongpair($a0) {
+ my @a = sort {$a <=> $b} keys %{{map {$_ => 1} @{$a0}}};
+ my $count = 0;
+ my $ip = combinations(\@a, 2);
+ while (my $c = $ip->next) {
+ if (abs($c->[0] - $c->[1]) < min(@{$c})) {
+ $count++;
+ }
+ }
+ return $count;
+}
diff --git a/challenge-277/roger-bell-west/postscript/ch-1.ps b/challenge-277/roger-bell-west/postscript/ch-1.ps
new file mode 100644
index 0000000000..385d2f09fc
--- /dev/null
+++ b/challenge-277/roger-bell-west/postscript/ch-1.ps
@@ -0,0 +1,96 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/dget {
+ 3 1 roll
+ 2 copy
+ known {
+ get exch pop
+ } {
+ pop pop
+ } ifelse
+} bind def
+
+/filter { % array proc(bool) -> array
+ 1 dict begin
+ /p exch def
+ [ exch
+ {
+ dup p not
+ {
+ pop
+ } if
+ } forall
+ ]
+ end
+} bind def
+
+/keys { % dict -> array of dict keys
+ [ exch
+ {
+ pop
+ } forall
+ ]
+} bind def
+
+/test.end {
+ ( ) print
+ test.count 0 gt {
+ (Passed ) print
+ test.pass (...) cvs print
+ (/) print
+ test.count (...) cvs print
+ ( \() print
+ test.pass 100 mul test.count idiv (...) cvs print
+ (%\)) print
+ (\r\n) print
+ } if
+} bind def
+
+/test.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} bind def
+
+/test {
+ /test.count test.count 1 add def
+ {
+ /test.pass test.pass 1 add def
+ } {
+ ( ) print
+ test.count (....) cvs print
+ (-fail) print
+ } ifelse
+} bind def
+
+
+% end included library code
+
+/countcommon {
+ 0 dict begin
+ /bc 0 dict def
+ {
+ /w exch def
+ bc w bc w 0 dget 1 add put
+ } forall
+ /ac 0 dict def
+ {
+ /w exch def
+ ac w ac w 0 dget 1 add put
+ } forall
+ ac keys {
+ /k exch def
+ ac k get 1 eq
+ bc k 0 dget 1 eq
+ and
+ } filter length
+ end
+} bind def
+
+(countcommon) test.start
+[(Perl) (is) (my) (friend)] [(Perl) (and) (Raku) (are) (friend)] countcommon 2 eq test
+[(Perl) (and) (Python) (are) (very) (similar)] [(Python) (is) (top) (in) (guest) (languages)] countcommon 1 eq test
+[(Perl) (is) (imperative) (Lisp) (is) (functional)] [(Crystal) (is) (similar) (to) (Ruby)] countcommon 0 eq test
+test.end
diff --git a/challenge-277/roger-bell-west/postscript/ch-2.ps b/challenge-277/roger-bell-west/postscript/ch-2.ps
new file mode 100644
index 0000000000..037bd5101a
--- /dev/null
+++ b/challenge-277/roger-bell-west/postscript/ch-2.ps
@@ -0,0 +1,219 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/quicksort {
+ { quicksort.cmp } quicksort.with_comparator
+} bind def
+
+/test.end {
+ ( ) print
+ test.count 0 gt {
+ (Passed ) print
+ test.pass (...) cvs print
+ (/) print
+ test.count (...) cvs print
+ ( \() print
+ test.pass 100 mul test.count idiv (...) cvs print
+ (%\)) print
+ (\r\n) print
+ } if
+} bind def
+
+/quicksort.main { % lo hi -> (null)
+ 3 dict begin
+ /hi exch def
+ /lo exch def
+ /xit false def
+ lo 0 lt {
+ /xit true def
+ } if
+ hi 0 lt {
+ /xit true def
+ } if
+ lo hi ge {
+ /xit true def
+ } if
+ xit not {
+ /p quicksort.partition def
+ lo p quicksort.main
+ p 1 add hi quicksort.main
+ } if
+ end
+} bind def
+
+/listmin {
+ { min } reduce
+} bind def
+
+/test {
+ /test.count test.count 1 add def
+ {
+ /test.pass test.pass 1 add def
+ } {
+ ( ) print
+ test.count (....) cvs print
+ (-fail) print
+ } ifelse
+} bind def
+
+/quicksort.with_comparator { % [ a c b ] { comparator } -> [ a b c ]
+ 2 dict begin
+ /cmp exch def
+ /arr exch def
+ arr length 0 gt {
+ 0 arr length 1 sub quicksort.main
+ } if
+ arr
+ end
+} bind def
+
+/quicksort.swap {
+ 2 dict begin
+ /bi exch def
+ /ai exch def
+ arr ai get
+ arr bi get
+ arr exch ai exch put
+ arr exch bi exch put
+ end
+} bind def
+
+/toset { % array -> dict of (value, true)
+ << exch
+ {
+ true
+ } forall
+ >>
+} bind def
+
+/keys { % dict -> array of dict keys
+ [ exch
+ {
+ pop
+ } forall
+ ]
+} bind def
+
+/test.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} bind def
+
+/reduce { % array proc -> value
+ 2 dict begin
+ /p exch def
+ /a exch def
+ a 0 get
+ 1 1 a length 1 sub {
+ a exch get
+ p
+ } for
+ end
+} bind def
+
+/combinations {
+ 4 dict begin
+ /k exch def
+ /arr exch def
+ /c [
+ 0 1 k 1 sub { } for
+ arr length
+ 0
+ ] def
+ [
+ {
+ [
+ k 1 sub -1 0 {
+ c exch get arr exch get
+ } for
+ ]
+ /j 0 def
+ {
+ c j get 1 add c j 1 add get ne {
+ exit
+ } if
+ c j j put
+ /j j 1 add def
+ } loop
+ j k ge {
+ exit
+ } if
+ c j c j get 1 add put
+ } loop
+ ]
+ end
+} bind def
+
+/quicksort.cmp {
+ 2 copy
+ lt {
+ pop pop -1
+ } {
+ gt {
+ 1
+ } {
+ 0
+ } ifelse
+ } ifelse
+} bind def
+
+/quicksort.partition {
+ 3 dict begin
+ /pivot arr hi lo add 2 idiv get def
+ /i lo 1 sub def
+ /j hi 1 add def
+ {
+ {
+ /i i 1 add def
+ arr i get pivot cmp 0 ge {
+ exit
+ } if
+ } loop
+ {
+ /j j 1 sub def
+ arr j get pivot cmp 0 le {
+ exit
+ } if
+ } loop
+ i j ge {
+ j
+ exit
+ } if
+ i j quicksort.swap
+ } loop
+ end
+} bind def
+
+/filter { % array proc(bool) -> array
+ 1 dict begin
+ /p exch def
+ [ exch
+ {
+ dup p not
+ {
+ pop
+ } if
+ } forall
+ ]
+ end
+} bind def
+
+
+% end included library code
+
+/strongpair {
+ 0 dict begin
+ toset keys quicksort
+ 2 combinations {
+ /c exch def
+ c 0 get c 1 get sub abs c listmin lt
+ } filter length
+ end
+} bind def
+
+(strongpair) test.start
+[1 2 3 4 5] strongpair 4 eq test
+[5 7 1 7] strongpair 1 eq test
+test.end
diff --git a/challenge-277/roger-bell-west/raku/ch-1.p6 b/challenge-277/roger-bell-west/raku/ch-1.p6
new file mode 100755
index 0000000000..27bbb9d494
--- /dev/null
+++ b/challenge-277/roger-bell-west/raku/ch-1.p6
@@ -0,0 +1,19 @@
+#! /usr/bin/raku
+
+use Test;
+
+plan 3;
+
+is(countcommon(['Perl', 'is', 'my', 'friend'], ['Perl', 'and', 'Raku', 'are', 'friend']), 2, 'example 1');
+is(countcommon(['Perl', 'and', 'Python', 'are', 'very', 'similar'], ['Python', 'is', 'top', 'in', 'guest', 'languages']), 1, 'example 2');
+is(countcommon(['Perl', 'is', 'imperative', 'Lisp', 'is', 'functional'], ['Crystal', 'is', 'similar', 'to', 'Ruby']), 0, 'example 3');
+
+sub countcommon(@a, @b) {
+ my %ac;
+ map {%ac{$_}++}, @a;
+ my %bc;
+ map {%bc{$_}++}, @b;
+ return %ac.keys.grep({%ac{$_} == 1 &&
+ (%bc{$_}:exists) &&
+ %bc{$_} == 1}).elems;
+}
diff --git a/challenge-277/roger-bell-west/raku/ch-2.p6 b/challenge-277/roger-bell-west/raku/ch-2.p6
new file mode 100755
index 0000000000..008976edd6
--- /dev/null
+++ b/challenge-277/roger-bell-west/raku/ch-2.p6
@@ -0,0 +1,13 @@
+#! /usr/bin/raku
+
+use Test;
+
+plan 2;
+
+is(strongpair([1, 2, 3, 4, 5]), 4, 'example 1');
+is(strongpair([5, 7, 1, 7]), 1, 'example 2');
+
+sub strongpair(@a0) {
+ my @a = @a0.unique.sort({$^a <=> $^b});
+ return @a.combinations(2).grep({abs($_[0]-$_[1]) < min($_)}).elems;
+}
diff --git a/challenge-277/roger-bell-west/rust/ch-1.rs b/challenge-277/roger-bell-west/rust/ch-1.rs
new file mode 100755
index 0000000000..88116b39e7
--- /dev/null
+++ b/challenge-277/roger-bell-west/rust/ch-1.rs
@@ -0,0 +1,42 @@
+use counter::Counter;
+
+#[test]
+fn test_ex1() {
+ assert_eq!(
+ countcommon(
+ vec!["Perl", "is", "my", "friend"],
+ vec!["Perl", "and", "Raku", "are", "friend"]
+ ),
+ 2
+ );
+}
+
+#[test]
+fn test_ex2() {
+ assert_eq!(
+ countcommon(
+ vec!["Perl", "and", "Python", "are", "very", "similar"],
+ vec!["Python", "is", "top", "in", "guest", "languages"]
+ ),
+ 1
+ );
+}
+
+#[test]
+fn test_ex3() {
+ assert_eq!(
+ countcommon(
+ vec!["Perl", "is", "imperative", "Lisp", "is", "functional"],
+ vec!["Crystal", "is", "similar", "to", "Ruby"]
+ ),
+ 0
+ );
+}
+
+fn countcommon(a: Vec<&str>, b: Vec<&str>) -> usize {
+ let ac = a.into_iter().collect::<Counter<_>>();
+ let bc = b.into_iter().collect::<Counter<_>>();
+ let ch = ac.clone() | bc.clone();
+ let cl = ac & bc;
+ cl.keys().filter(|k| *ch.get(*k).unwrap() == 1).count()
+}
diff --git a/challenge-277/roger-bell-west/rust/ch-2.rs b/challenge-277/roger-bell-west/rust/ch-2.rs
new file mode 100755
index 0000000000..516c6b569d
--- /dev/null
+++ b/challenge-277/roger-bell-west/rust/ch-2.rs
@@ -0,0 +1,23 @@
+use itertools::Itertools;
+
+#[test]
+fn test_ex1() {
+ assert_eq!(strongpair(vec![1, 2, 3, 4, 5]), 4);
+}
+
+#[test]
+fn test_ex2() {
+ assert_eq!(strongpair(vec![5, 7, 1, 7]), 1);
+}
+
+fn strongpair(a0: Vec<i32>) -> usize {
+ let mut a = a0.clone();
+ a.sort();
+ a.dedup();
+ a.iter()
+ .combinations(2)
+ .filter(|c| {
+ (c[0] - c[1]).abs() < **c.iter().min().unwrap()
+ })
+ .count()
+}
diff --git a/challenge-277/roger-bell-west/tests.json b/challenge-277/roger-bell-west/tests.json
new file mode 100644
index 0000000000..019b00ec19
--- /dev/null
+++ b/challenge-277/roger-bell-west/tests.json
@@ -0,0 +1,40 @@
+{
+ "ch-1" : [
+ {
+ "function" : "countcommon",
+ "multiarg" : true,
+ "arguments" : [
+ [ "Perl", "is", "my", "friend" ],
+ [ "Perl", "and", "Raku", "are", "friend" ]
+ ],
+ "result" : 2
+ },
+ {
+ "multiarg" : true,
+ "arguments" : [
+ [ "Perl", "and", "Python", "are", "very", "similar" ],
+ [ "Python", "is", "top", "in", "guest", "languages" ]
+ ],
+ "result" : 1
+ },
+ {
+ "multiarg" : true,
+ "arguments" : [
+ [ "Perl", "is", "imperative", "Lisp", "is", "functional" ],
+ [ "Crystal", "is", "similar", "to", "Ruby" ]
+ ],
+ "result" : 0
+ }
+ ],
+ "ch-2" : [
+ {
+ "function" : "strongpair",
+ "arguments" : [ 1, 2, 3, 4, 5 ],
+ "result" : 4
+ },
+ {
+ "arguments" : [ 5, 7, 1, 7 ],
+ "result" : 1
+ }
+ ]
+}