aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorE. Choroba <choroba@matfyz.cz>2023-09-19 12:54:13 +0200
committerE. Choroba <choroba@matfyz.cz>2023-09-19 12:54:13 +0200
commit184b0c6adf491f1c39110b7f3200110fe5325ce2 (patch)
tree34faf886954be8546699bd9cb6215af45bbee60d
parentaee701524950403dce06a2a835452b79eacabce1 (diff)
downloadperlweeklychallenge-club-184b0c6adf491f1c39110b7f3200110fe5325ce2.tar.gz
perlweeklychallenge-club-184b0c6adf491f1c39110b7f3200110fe5325ce2.tar.bz2
perlweeklychallenge-club-184b0c6adf491f1c39110b7f3200110fe5325ce2.zip
Add solutions to 235: Remove One & Duplicate Zeros by E. Choroba
-rwxr-xr-xchallenge-235/e-choroba/perl/ch-1.pl58
-rwxr-xr-xchallenge-235/e-choroba/perl/ch-2.pl26
2 files changed, 84 insertions, 0 deletions
diff --git a/challenge-235/e-choroba/perl/ch-1.pl b/challenge-235/e-choroba/perl/ch-1.pl
new file mode 100755
index 0000000000..30f9e2ff73
--- /dev/null
+++ b/challenge-235/e-choroba/perl/ch-1.pl
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use experimental qw( signatures );
+
+sub remove_one(@ints) {
+ my @fails = grep $ints[ $_ - 1 ] >= $ints[$_], 1 .. $#ints;
+
+ return ! @fails if 1 != @fails;
+
+ # We can remove the first or last int.
+ return 1 if $fails[0] == 1 || $fails[0] == $#ints;
+
+ return 1
+ # Remove the lesser number (0 from 6 12 [0] 18)
+ if $fails[0] < $#ints && $ints[ $fails[0] - 1 ] < $ints[ $fails[0] + 1 ]
+ # Remove the previous number (9 from 2 9 [4] 6)
+ || $fails[0] > 1 && $ints[ $fails[0] - 2 ] < $ints[ $fails[0] ];
+
+ return
+}
+
+sub remove_one_brute_force(@ints) {
+ REMOVE:
+ for my $i (0 .. $#ints) {
+ my @copy = @ints;
+ splice @copy, $i, 1;
+ for my $j (1 .. $#copy) {
+ next REMOVE if $copy[ $j - 1 ] >= $copy[$j];
+ }
+ return 1
+ }
+ return
+}
+
+use Test::More tests => 3 + 5;
+
+ok remove_one(0, 2, 9, 4, 6), 'Example 1';
+ok ! remove_one(5, 1, 3, 2), 'Example 2';
+ok remove_one(2, 2, 3), 'Example 3';
+
+ok remove_one(6, 12, 0, 18), 'Remove the lesser number';
+ok remove_one(5, 1, 2, 3), 'First';
+ok remove_one(1, 2, 3, 0), 'Last';
+ok ! remove_one(0, 2, 9, 1, 6), 'Two removals needed';
+
+use Benchmark qw{ cmpthese };
+my @ints = map int(rand(200)), 1 .. 40;
+is ! remove_one_brute_force(@ints), ! remove_one(@ints), 'Long';
+cmpthese(-3, {
+ brute_force => sub { remove_one_brute_force(@ints) },
+ optimized => sub { remove_one(@ints) },
+});
+
+__END__
+ Rate brute_force optimized
+brute_force 16188/s -- -90%
+optimized 157390/s 872% --
diff --git a/challenge-235/e-choroba/perl/ch-2.pl b/challenge-235/e-choroba/perl/ch-2.pl
new file mode 100755
index 0000000000..1c682f3004
--- /dev/null
+++ b/challenge-235/e-choroba/perl/ch-2.pl
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use experimental qw( signatures );
+
+sub duplicate_zeros(@ints) {
+ my @d;
+ for my $int (@ints) {
+ push @d, ($int) x (1 + (0 == $int));
+ last if @d > @ints
+ }
+ return [@d[0 .. $#ints]]
+}
+
+sub duplicate_zeros_laconic(@ints) {
+ [(map +($_) x (1 + (0 == $_)), @ints)[0 .. $#ints]]
+}
+
+use Test2::V0;
+plan 3 + 3;
+
+for my $d (*duplicate_zeros{CODE}, *duplicate_zeros_laconic{CODE}) {
+ is $d->(1, 0, 2, 3, 0, 4, 5, 0), [1, 0, 0, 2, 3, 0, 0, 4], 'Example 1';
+ is $d->(1, 2, 3), [1, 2, 3], 'Example 2';
+ is $d->(0, 3, 0, 4, 5), [0, 0, 3, 0, 0], 'Example 3';
+}