diff options
| author | Roger Bell_West <roger@firedrake.org> | 2023-02-28 15:33:40 +0000 |
|---|---|---|
| committer | Roger Bell_West <roger@firedrake.org> | 2023-02-28 15:33:40 +0000 |
| commit | ea45bdcaaf4c97d781c685f828aaba8a39f6cfad (patch) | |
| tree | 13e4a31e219283e94dcd687523965e20a07c7f6d | |
| parent | 09eef326c170759598ee2d5d35a5aad50be4a11c (diff) | |
| download | perlweeklychallenge-club-ea45bdcaaf4c97d781c685f828aaba8a39f6cfad.tar.gz perlweeklychallenge-club-ea45bdcaaf4c97d781c685f828aaba8a39f6cfad.tar.bz2 perlweeklychallenge-club-ea45bdcaaf4c97d781c685f828aaba8a39f6cfad.zip | |
RogerBW solutions for challenge no. 206
| -rwxr-xr-x | challenge-206/roger-bell-west/perl/ch-1.pl | 27 | ||||
| -rwxr-xr-x | challenge-206/roger-bell-west/perl/ch-2.pl | 37 | ||||
| -rw-r--r-- | challenge-206/roger-bell-west/postscript/ch-1.ps | 105 | ||||
| -rw-r--r-- | challenge-206/roger-bell-west/postscript/ch-2.ps | 199 | ||||
| -rwxr-xr-x | challenge-206/roger-bell-west/python/ch-1.py | 32 | ||||
| -rwxr-xr-x | challenge-206/roger-bell-west/python/ch-2.py | 31 | ||||
| -rwxr-xr-x | challenge-206/roger-bell-west/raku/ch-1.p6 | 21 | ||||
| -rwxr-xr-x | challenge-206/roger-bell-west/raku/ch-2.p6 | 30 | ||||
| -rwxr-xr-x | challenge-206/roger-bell-west/ruby/ch-1.rb | 34 | ||||
| -rwxr-xr-x | challenge-206/roger-bell-west/ruby/ch-2.rb | 44 | ||||
| -rwxr-xr-x | challenge-206/roger-bell-west/rust/ch-1.rs | 34 | ||||
| -rwxr-xr-x | challenge-206/roger-bell-west/rust/ch-2.rs | 38 | ||||
| -rw-r--r-- | challenge-206/roger-bell-west/tests.yaml | 36 |
13 files changed, 668 insertions, 0 deletions
diff --git a/challenge-206/roger-bell-west/perl/ch-1.pl b/challenge-206/roger-bell-west/perl/ch-1.pl new file mode 100755 index 0000000000..0ec8a1447c --- /dev/null +++ b/challenge-206/roger-bell-west/perl/ch-1.pl @@ -0,0 +1,27 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 3; + +is(shortesttime(['00:00', '23:55', '20:00']), 5, 'example 1'); +is(shortesttime(['01:01', '00:50', '00:57']), 4, 'example 2'); +is(shortesttime(['10:10', '09:30', '09:00', '09:55']), 15, 'example 3'); + +use Algorithm::Combinatorics qw(combinations); +use List::Util qw(min); + +sub shortesttime($n) { + my $dl = 1440; + my @nl = map {/(\d+):(\d+)/; 60*$1+$2} @{$n}; + my $i = combinations(\@nl, 2); + my @o; + while (my $p = $i->next) { + my $d = abs($p->[0] - $p->[1]); + push @o, $d; + push @o, $dl - $d; + } + return min(@o); +} diff --git a/challenge-206/roger-bell-west/perl/ch-2.pl b/challenge-206/roger-bell-west/perl/ch-2.pl new file mode 100755 index 0000000000..570dc5257b --- /dev/null +++ b/challenge-206/roger-bell-west/perl/ch-2.pl @@ -0,0 +1,37 @@ +#! /usr/bin/perl + +use strict; +use warnings; +use experimental 'signatures'; + +use Test::More tests => 2; + +is(arraypairing([1, 2, 3, 4]), 4, 'example 1'); +is(arraypairing([0, 2, 1, 3]), 2, 'example 2'); + +use Algorithm::Combinatorics qw(combinations permutations); +use List::Util qw(min max); + +sub arraypairing($n) { + my $nl = scalar @{$n}; + if ($nl % 2 == 1) { + return 0; + } + my $hl = $nl / 2; + my @out; + my $ic = combinations([0 .. $nl-1], $hl); + while (my $px = $ic->next) { + my @pa = map {$n->[$_]} @{$px}; + my %ps = map {$_ => 1} @{$px}; + my @pb = map {$n->[$_]} grep {!exists $ps{$_}} (0 .. $nl-1); + my $ip = permutations(\@pa); + while (my $pp = $ip->next) { + my $s = 0; + foreach my $i (0 .. $hl-1) { + $s += min($pp->[$i], $pb[$i]); + } + push @out,$s; + } + } + return max(@out); +} diff --git a/challenge-206/roger-bell-west/postscript/ch-1.ps b/challenge-206/roger-bell-west/postscript/ch-1.ps new file mode 100644 index 0000000000..371ba76a41 --- /dev/null +++ b/challenge-206/roger-bell-west/postscript/ch-1.ps @@ -0,0 +1,105 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/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 + +/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 + +/listmin { + { min } reduce +} bind def + +/test.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} 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 + +/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 + +/shortesttime { + [ exch + { + dup 0 2 getinterval cvi 60 mul exch 3 2 getinterval cvi add + } forall + ] + [ exch + 2 combinations { + aload pop sub abs dup 1440 exch sub + } forall + ] listmin +} bind def + +(shortesttime) test.start +[(00:00) (23:55) (20:00)] shortesttime 5 eq test +[(01:01) (00:50) (00:57)] shortesttime 4 eq test +[(10:10) (09:30) (09:00) (09:55)] shortesttime 15 eq test +test.end diff --git a/challenge-206/roger-bell-west/postscript/ch-2.ps b/challenge-206/roger-bell-west/postscript/ch-2.ps new file mode 100644 index 0000000000..c1a53697c2 --- /dev/null +++ b/challenge-206/roger-bell-west/postscript/ch-2.ps @@ -0,0 +1,199 @@ +%!PS + +% begin included library code +% see https://codeberg.org/Firedrake/postscript-libraries/ +/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 + +/test.start { + print (:) print + /test.pass 0 def + /test.count 0 def +} 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 + +/map { % array proc -> array + 2 dict begin + /p exch def + [ exch + { + p + } forall + ] + end +} 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 + +/permute { % [array] {proc} permute runs proc on each permutation of array + 7 dict begin + /permute.subproc exch def + /permute.a exch def + /permute.n permute.a length def + /permute.c [ permute.n { 0 } repeat ] def + permute.a permute.subproc + /permute.i 0 def + { + permute.i permute.n ge { + exit + } if + permute.c permute.i get permute.i lt { + permute.i 2 mod 0 eq { + 0 permute.i permute.swap + } { + permute.c permute.i get permute.i permute.swap + } ifelse + permute.a permute.subproc + permute.c permute.i get 1 add permute.c exch permute.i exch put + /permute.i 0 def + } { + permute.c permute.i 0 put + /permute.i permute.i 1 add def + } ifelse + } loop + end +} 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 + +/filter { % array proc(bool) -> array + 1 dict begin + /p exch def + [ exch + { + dup p not + { + pop + } if + } forall + ] + end +} bind def + +/permute.swap { + /permute.bi exch def + /permute.ai exch def + permute.a permute.ai get + permute.a permute.bi get + permute.a exch permute.ai exch put + permute.a exch permute.bi exch put +} bind def + +/toset { % array -> dict of (value, true) + << exch + { + true + } forall + >> +} bind def + +/listmax { + { max } reduce +} bind def + + +% end included library code + +/arraypairing { + 9 dict begin + /n exch def + /nl n length def + nl 2 mod 1 eq { + 0 + } { + /hl nl 2 idiv def + [ + [ 0 1 nl 1 sub {} for ] + hl + combinations { + /px exch def + /pa [ + px { + n exch get + } forall + ] def + /ps px toset def + /pb [ 0 1 nl 1 sub {} for ] + { ps exch known not } filter + { n exch get } map def + pa { + /pp exch def + /s 0 def + 0 1 hl 1 sub { + /i exch def + /s pp i get pb i get min s add def + } for + s + } permute + } forall + ] listmax + } ifelse + end +} bind def + +(arraypairing) test.start +[1 2 3 4] arraypairing 4 eq test +[0 2 1 3] arraypairing 2 eq test +test.end diff --git a/challenge-206/roger-bell-west/python/ch-1.py b/challenge-206/roger-bell-west/python/ch-1.py new file mode 100755 index 0000000000..1315f73ccf --- /dev/null +++ b/challenge-206/roger-bell-west/python/ch-1.py @@ -0,0 +1,32 @@ +#! /usr/bin/python3 + +import unittest + +from datetime import time +from itertools import combinations + +def shortesttime(n): + dl = 1440 + ni = [] + for x in n: + t = time.fromisoformat(x + ":00") + ni.append(t.hour * 60 + t.minute) + o = [] + for p in combinations(ni, 2): + d = abs(p[0] - p[1]) + o.append(d) + o.append(dl - d) + return min(o) + +class TestShortesttime(unittest.TestCase): + + def test_ex1(self): + self.assertEqual(shortesttime(["00:00", "23:55", "20:00"]), 5, 'example 1') + + def test_ex2(self): + self.assertEqual(shortesttime(["01:01", "00:50", "00:57"]), 4, 'example 2') + + def test_ex3(self): + self.assertEqual(shortesttime(["10:10", "09:30", "09:00", "09:55"]), 15, 'example 3') + +unittest.main() diff --git a/challenge-206/roger-bell-west/python/ch-2.py b/challenge-206/roger-bell-west/python/ch-2.py new file mode 100755 index 0000000000..bcd87e7cfd --- /dev/null +++ b/challenge-206/roger-bell-west/python/ch-2.py @@ -0,0 +1,31 @@ +#! /usr/bin/python3 + +import unittest +from itertools import permutations, combinations + +def arraypairing(n): + nl = len(n) + if nl % 2 == 1: + return 0 + hl = nl // 2 + out = [] + for px in combinations(range(nl), hl): + pa = [n[i] for i in px] + ps = set(px) + pb = [n[i] for i in range(nl) if i not in ps] + for pp in permutations(pa): + s = 0 + for i in range(hl): + s += min(pp[i], pb[i]) + out.append(s) + return max(out) + +class TestArraypairing(unittest.TestCase): + + def test_ex1(self): + self.assertEqual(arraypairing([1, 2, 3, 4]), 4, 'example 1') + + def test_ex2(self): + self.assertEqual(arraypairing([0, 2, 1, 3]), 2, 'example 2') + +unittest.main() diff --git a/challenge-206/roger-bell-west/raku/ch-1.p6 b/challenge-206/roger-bell-west/raku/ch-1.p6 new file mode 100755 index 0000000000..1f7016627c --- /dev/null +++ b/challenge-206/roger-bell-west/raku/ch-1.p6 @@ -0,0 +1,21 @@ +#! /usr/bin/raku + +use Test; + +plan 3; + +is(shortesttime(['00:00', '23:55', '20:00']), 5, 'example 1'); +is(shortesttime(['01:01', '00:50', '00:57']), 4, 'example 2'); +is(shortesttime(['10:10', '09:30', '09:00', '09:55']), 15, 'example 3'); + +sub shortesttime(@n) { + my $dl = 1440; + my @nl = @n.map({$_.substr(0, 2) * 60 + $_.substr(3, 2)}); + my @o; + for @nl.combinations(2) -> @p { + my $d = abs(@p[0] - @p[1]); + @o.push($d); + @o.push($dl - $d); + } + return min(@o); +} diff --git a/challenge-206/roger-bell-west/raku/ch-2.p6 b/challenge-206/roger-bell-west/raku/ch-2.p6 new file mode 100755 index 0000000000..dc1107631e --- /dev/null +++ b/challenge-206/roger-bell-west/raku/ch-2.p6 @@ -0,0 +1,30 @@ +#! /usr/bin/raku + +use Test; + +plan 2; + +is(arraypairing([1, 2, 3, 4]), 4, 'example 1'); +is(arraypairing([0, 2, 1, 3]), 2, 'example 2'); + +sub arraypairing(@n) { + my $nl = @n.elems; + if ($nl % 2 == 1) { + return 0; + } + my $hl = $nl div 2; + my @out; + for [0 .. $nl-1].combinations(2) -> @px { + my @pa = map {@n[$_]},@px; + my $ps = @px.Set; + my @pb = map {@n[$_]}, grep {$ps{$_}:!exists}, (0 .. $nl-1); + for @pa.permutations -> @pp { + my $s = 0; + for (0 .. $hl-1) -> $i { + $s += min(@pp[$i], @pb[$i]); + } + @out.push($s); + } + } + return max(@out); +} diff --git a/challenge-206/roger-bell-west/ruby/ch-1.rb b/challenge-206/roger-bell-west/ruby/ch-1.rb new file mode 100755 index 0000000000..82418dda84 --- /dev/null +++ b/challenge-206/roger-bell-west/ruby/ch-1.rb @@ -0,0 +1,34 @@ +#! /usr/bin/ruby + +require 'test/unit' + +def shortesttime(n) + dl = 1440 + ni = [] + for x in n do + ni.push(x[0..1].to_i * 60 + x[3..4].to_i) + end + o = [] + ni.combination(2) do |p| + d = (p[0] - p[1]).abs + o.push(d) + o.push(dl - d) + end + return o.min +end + +class TestShortesttime < Test::Unit::TestCase + + def test_ex1 + assert_equal(5, shortesttime(['00:00', '23:55', '20:00'])) + end + + def test_ex2 + assert_equal(4, shortesttime(['01:01', '00:50', '00:57'])) + end + + def test_ex3 + assert_equal(15, shortesttime(['10:10', '09:30', '09:00', '09:55'])) + end + +end diff --git a/challenge-206/roger-bell-west/ruby/ch-2.rb b/challenge-206/roger-bell-west/ruby/ch-2.rb new file mode 100755 index 0000000000..7f861c6095 --- /dev/null +++ b/challenge-206/roger-bell-west/ruby/ch-2.rb @@ -0,0 +1,44 @@ +#! /usr/bin/ruby + +require 'test/unit' + +require 'set' + +def arraypairing(n) + nl = n.length + if nl % 2 == 1 then + return 0 + end + hl = nl.div(2) + out = [] + 0.upto(nl-1).to_a.combination(hl).each do |px| + pa = px.map{|i| n[i]} + ps = Set.new(px) + pb = [] + n.each_with_index do |ni, i| + if !ps.include?(i) then + pb.push(ni) + end + end + pa.permutation.each do |pp| + s = 0 + 0.upto(hl-1) do |i| + s += [pp[i], pb[i]].min + end + out.push(s) + end + end + return out.max +end + +class TestArraypairing < Test::Unit::TestCase + + def test_ex1 + assert_equal(4, arraypairing([1, 2, 3, 4])) + end + +# def test_ex2 +# assert_equal(2, arraypairing([0, 2, 1, 3])) +# end + +end diff --git a/challenge-206/roger-bell-west/rust/ch-1.rs b/challenge-206/roger-bell-west/rust/ch-1.rs new file mode 100755 index 0000000000..2d2290423a --- /dev/null +++ b/challenge-206/roger-bell-west/rust/ch-1.rs @@ -0,0 +1,34 @@ +use itertools::Itertools; + +#[test] +fn test_ex1() { + assert_eq!(shortesttime(vec!["00:00", "23:55", "20:00"]), 5); +} + +#[test] +fn test_ex2() { + assert_eq!(shortesttime(vec!["01:01", "00:50", "00:57"]), 4); +} + +#[test] +fn test_ex3() { + assert_eq!(shortesttime(vec!["10:10", "09:30", "09:00", "09:55"]), 15); +} + +fn shortesttime(n: Vec<&str>) -> isize { + let dl = 1440; + let mut ni = Vec::new(); + for x in n { + ni.push( + x[0..=1].parse::<isize>().unwrap() * 60 + + x[3..=4].parse::<isize>().unwrap(), + ); + } + let mut o = Vec::new(); + for p in ni.iter().combinations(2) { + let d = (p[0] - p[1]).abs(); + o.push(d); + o.push(dl - d); + } + *o.iter().min().unwrap() +} diff --git a/challenge-206/roger-bell-west/rust/ch-2.rs b/challenge-206/roger-bell-west/rust/ch-2.rs new file mode 100755 index 0000000000..69b410ed72 --- /dev/null +++ b/challenge-206/roger-bell-west/rust/ch-2.rs @@ -0,0 +1,38 @@ +use itertools::Itertools; +use std::cmp::min; +use std::collections::HashSet; + +#[test] +fn test_ex1() { + assert_eq!(arraypairing(vec![1, 2, 3, 4]), 4); +} + +#[test] +fn test_ex2() { + assert_eq!(arraypairing(vec![0, 2, 1, 3]), 2); +} + +fn arraypairing(n: Vec<usize>) -> usize { + let nl = n.len(); + if nl % 2 == 1 { + return 0; + } + let hl = nl / 2; + let mut out = Vec::new(); + for px in (0..nl).combinations(hl) { + let pa = px.iter().map(|i| n[*i]).collect::<Vec<usize>>(); + let ps: HashSet<usize> = HashSet::from_iter(px.into_iter()); + let pb = (0..nl) + .filter(|i| !ps.contains(i)) + .map(|i| n[i]) + .collect::<Vec<usize>>(); + for pp in pa.iter().permutations(hl) { + let mut s = 0; + for i in 0..hl { + s += min(pp[i], &pb[i]); + } + out.push(s) + } + } + *out.iter().max().unwrap() +} diff --git a/challenge-206/roger-bell-west/tests.yaml b/challenge-206/roger-bell-west/tests.yaml new file mode 100644 index 0000000000..3a31049500 --- /dev/null +++ b/challenge-206/roger-bell-west/tests.yaml @@ -0,0 +1,36 @@ +--- +ch-1: + - function: shortesttime + arguments: + - 00:00 + - 23:55 + - 20:00 + result: 5 + - function: shortesttime + arguments: + - 01:01 + - 00:50 + - 00:57 + result: 4 + - function: shortesttime + arguments: + - 10:10 + - 09:30 + - 09:00 + - 09:55 + result: 15 +ch-2: + - function: arraypairing + arguments: + - 1 + - 2 + - 3 + - 4 + result: 4 + - function: arraypairing + arguments: + - 0 + - 2 + - 1 + - 3 + result: 2 |
