diff options
| author | E. Choroba <choroba@matfyz.cz> | 2023-09-19 12:54:13 +0200 |
|---|---|---|
| committer | E. Choroba <choroba@matfyz.cz> | 2023-09-19 12:54:13 +0200 |
| commit | 184b0c6adf491f1c39110b7f3200110fe5325ce2 (patch) | |
| tree | 34faf886954be8546699bd9cb6215af45bbee60d | |
| parent | aee701524950403dce06a2a835452b79eacabce1 (diff) | |
| download | perlweeklychallenge-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-x | challenge-235/e-choroba/perl/ch-1.pl | 58 | ||||
| -rwxr-xr-x | challenge-235/e-choroba/perl/ch-2.pl | 26 |
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'; +} |
