diff options
| author | E. Choroba <choroba@matfyz.cz> | 2021-12-14 00:01:29 +0100 |
|---|---|---|
| committer | E. Choroba <choroba@matfyz.cz> | 2021-12-14 00:01:29 +0100 |
| commit | 38321bcb275b6e3bb9e55c55e4ff7122438d16b6 (patch) | |
| tree | cb7da06e3b9d6dff3d2b17fbc57208c276564faa | |
| parent | ecafe0e840b90c1462ec4ac924f3255dd3beb2c0 (diff) | |
| download | perlweeklychallenge-club-38321bcb275b6e3bb9e55c55e4ff7122438d16b6.tar.gz perlweeklychallenge-club-38321bcb275b6e3bb9e55c55e4ff7122438d16b6.tar.bz2 perlweeklychallenge-club-38321bcb275b6e3bb9e55c55e4ff7122438d16b6.zip | |
Add solutions to 143: Calculator & Stealthy Number by E. Choroba
| -rwxr-xr-x | challenge-143/e-choroba/perl/ch-1.pl | 62 | ||||
| -rwxr-xr-x | challenge-143/e-choroba/perl/ch-2.pl | 24 |
2 files changed, 86 insertions, 0 deletions
diff --git a/challenge-143/e-choroba/perl/ch-1.pl b/challenge-143/e-choroba/perl/ch-1.pl new file mode 100755 index 0000000000..b1e25bec50 --- /dev/null +++ b/challenge-143/e-choroba/perl/ch-1.pl @@ -0,0 +1,62 @@ +#!/usr/bin/perl +use warnings; +use strict; + +sub calculator { + my ($expression) = @_; + while ($expression =~ m{[ ()]}) { + $expression =~ s/(-?\d+) (\*) (-?\d+)/$1 * $3/e; + $expression =~ s/(-?\d+) ([-+]) (-?\d+)/"$1 $2 $3"/ee; + $expression =~ s/\((-?\d+)\)/$1/g; + } + return $expression +} + +use Marpa::R2; +my $dsl = << '__DSL__'; + + lexeme default = latm => 1 + :default ::= action => ::first + + Expression ::= Number + | ('(') Expression (')') assoc => group + || Expression (ws asterisk ws) Expression action => multiply + || Expression (ws plus ws) Expression action => add + | Expression (ws minus ws) Expression action => subtract + Number ::= Negative | positive + Negative ::= minus positive action => neg + + ws ~ [\s]+ + asterisk ~ '*' + plus ~ '+' + positive ~ [\d]+ + minus ~ '-' + +__DSL__ + +sub add { $_[1] + $_[2] } +sub subtract { $_[1] - $_[2] } +sub multiply { $_[1] * $_[2] } +sub neg { -$_[2] } +sub second { $_[2] } + +my $grammar = 'Marpa::R2::Scanless::G'->new({source => \$dsl}); + +sub calculate { + my ($input) = @_; + return ${ $grammar->parse(\$input, 'main') } +} + +use Test2::V0; +plan 8; + +my %tests = ( + 'Example 1' => ['10 + 20 - 5', 25], + 'Example 2' => ['(10 + 20 - 5) * 2', 50], + Negative => ['(1 + 2) - (1 * 12)', -9], + Precedence => ['((-1 - -2 - -3 * -4 + -5))', -16]); + +for my $t (sort keys %tests) { + is calculator($tests{$t}[0]), $tests{$t}[1], "regex $t"; + is calculate($tests{$t}[0]), $tests{$t}[1], "marpa $t"; +} diff --git a/challenge-143/e-choroba/perl/ch-2.pl b/challenge-143/e-choroba/perl/ch-2.pl new file mode 100755 index 0000000000..3feae62c6a --- /dev/null +++ b/challenge-143/e-choroba/perl/ch-2.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl +use warnings; +use strict; +use feature qw{ say }; + +sub stealthy_number { + my ($n) = @_; + my @divisors = (map $n / $_, grep 0 == $n % $_, 1 .. sqrt $n); + for my $A (@divisors) { + for my $C (@divisors) { + my $B = $n / $A; + my $D = $n / $C; + return 1 if $A + $B == $C + $D + 1; + } + } + return 0 +} + +use Test2::V0; +plan 3; + +is stealthy_number(36), 1, 'Example 1'; +is stealthy_number(12), 1, 'Example 2'; +is stealthy_number(6), 0, 'Example 3'; |
