diff options
| author | E. Choroba <choroba@matfyz.cz> | 2025-01-27 13:02:17 +0100 |
|---|---|---|
| committer | E. Choroba <choroba@matfyz.cz> | 2025-01-27 13:02:17 +0100 |
| commit | 393e259d003b34da2f52bef8c291102afc90afa9 (patch) | |
| tree | 48acf14aadaa129d9923fbae8e32ce73ed4a1b13 | |
| parent | 906bb690f8e1d091ac358c4ac77818bf879144c8 (diff) | |
| download | perlweeklychallenge-club-393e259d003b34da2f52bef8c291102afc90afa9.tar.gz perlweeklychallenge-club-393e259d003b34da2f52bef8c291102afc90afa9.tar.bz2 perlweeklychallenge-club-393e259d003b34da2f52bef8c291102afc90afa9.zip | |
Add solutions to 306: Odd Sum & Last Element by E. Choroba
| -rwxr-xr-x | challenge-306/e-choroba/perl/ch-1.pl | 51 | ||||
| -rwxr-xr-x | challenge-306/e-choroba/perl/ch-2.pl | 22 |
2 files changed, 73 insertions, 0 deletions
diff --git a/challenge-306/e-choroba/perl/ch-1.pl b/challenge-306/e-choroba/perl/ch-1.pl new file mode 100755 index 0000000000..938ee7720d --- /dev/null +++ b/challenge-306/e-choroba/perl/ch-1.pl @@ -0,0 +1,51 @@ +#!/usr/bin/perl +use warnings; +use strict; +use experimental qw( signatures ); + +# Using https://oeis.org/A143901. +sub odd_sum(@ints) { + my $sum = 0; + for my $m (1 .. @ints) { + my $n = @ints - $m + 1; + my $r = int(($m * $n + 1) / 2); + $sum += $r * $ints[$m - 1] + } + return $sum +} + +sub odd_sum_naive(@ints) { + my $sum = 0; + for my $from (0 .. $#ints) { + for my $length (1 .. $#ints - $from + 1) { + next if 0 == $length % 2; + + $sum += $_ for @ints[$from .. $from + $length - 1]; + } + } + return $sum +} + +use Test::More tests => (2 + 1) * 2; + +my %DISPATCH = (odd_sum => \&odd_sum, + odd_sum_naive => \&odd_sum_naive); + +my @long = sort grep ! /77/, 1 .. 500; +for my $odd_sum (qw( odd_sum odd_sum_naive )) { + is $DISPATCH{$odd_sum}(2, 5, 3, 6, 4), 77, "Example 1 $odd_sum"; + is $DISPATCH{$odd_sum}(1, 3), 4, "Example 2 $odd_sum"; + + is $DISPATCH{$odd_sum}(@long), 2856088560, "Long list $odd_sum"; +} + +use Benchmark qw{ cmpthese }; +cmpthese(-3, { + naive => sub { odd_sum_naive(@long) }, + fast => sub { odd_sum(@long) }, +}); + +__END__ + Rate naive fast +naive 2.45/s -- -100% +fast 7200/s 293300% -- diff --git a/challenge-306/e-choroba/perl/ch-2.pl b/challenge-306/e-choroba/perl/ch-2.pl new file mode 100755 index 0000000000..df8dbc2cf7 --- /dev/null +++ b/challenge-306/e-choroba/perl/ch-2.pl @@ -0,0 +1,22 @@ +#!/usr/bin/perl +use warnings; +use strict; +use feature qw{ say }; +use experimental qw( signatures ); + +sub last_element(@ints) { + while (@ints > 1) { + @ints = sort { $a <=> $b } @ints; + if ($ints[-1] == $ints[-2]) { + splice @ints, -2; + } else { + push @ints, pop(@ints) - pop @ints; + } + } + return $ints[0] // 0 +} + +use Test::More tests => 2; + +is last_element(3, 8, 5, 2, 9, 2), 1, 'Example 1'; +is last_element(3, 2, 5), 0, 'Example 2'; |
