diff options
| -rw-r--r-- | challenge-143/james-smith/README.md | 29 | ||||
| -rw-r--r-- | challenge-143/james-smith/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-143/james-smith/perl/ch-1.pl | 35 | ||||
| -rw-r--r-- | challenge-143/james-smith/perl/ch-2.pl | 33 |
4 files changed, 81 insertions, 17 deletions
diff --git a/challenge-143/james-smith/README.md b/challenge-143/james-smith/README.md index 90c0a8816c..67a6742064 100644 --- a/challenge-143/james-smith/README.md +++ b/challenge-143/james-smith/README.md @@ -1,4 +1,4 @@ -# Perl Weekly Challenge #142 +# Perl Weekly Challenge #143 You can find more information about this weeks, and previous weeks challenges at: @@ -10,32 +10,27 @@ submit solutions in whichever language you feel comfortable with. You can find the solutions here on github at: -https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-142/james-smith/perl +https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-143/james-smith/perl -# Challenge 1 - Divisor Last Digit +# Challenge 1 - Calculator -***You are given positive integers, `$m` and `$n`. Write a script to find total count of divisors of `$m` having last digit `$n`.*** +***You are given a string, `$s`, containing mathematical expression. Write a script to print the result of the mathematical expression. To keep it simple, please only accept `+ - * ()`.***` ## The solution ```perl -sub divisor_last_digit { - my($m,$n)=@_; - ($n==1?1:0)+grep{$_%10==$n} - map{$m%$_?():$m==$_*$_?($_):($_,$m/$_)} - 2..sqrt$m; +sub evaluate { + my $str = shift; + 1 while $str =~ s/\(\s*([^()]*?)\s*\)/ evaluate($1) /e; + 1 while $str =~ s/(-?\d+)\s*\*\s*(-?\d+)/ $1 * $2 /e; + 1 while $str =~ s/(-?\d+)\s*([-+])\s*(-?\d+)/$2 eq '+' ? $1+$3 : $1-$3/e; + return $str; } ``` - * First we find all the factors - by looping over all values between `2` and the square root of `$m`. If the value is a factor, so is `$m/$_`. - * We have a special case when `$m` is a square to avoid including the square root twice. - * We then `grep` to obtain those which have the correct last digit. - * There is one extra special case if `$n` is `1` we have to add `1` as `1` is a factor which we miss out in our calculations (so we don't - equally get `$m` as a factor). +# Challenge 2 - Stealthy Number -# Challenge 2 - Sleep sort - -***Another joke sort similar to JortSort suggested by champion Adam Russell. You are given a list of numbers. Write a script to implement Sleep Sort.*** +***You are given a positive number, `$n`. Write a script to find out if the given number is Stealthy Number. A positive integer `N` is stealthy, if there exist positive integers `a`, `b`, `c`, `d` such that `a * b = c * d = N` and `a + b = c + d + 1`.*** To perform a sleep sort - we loop through the list of numbers, sleeping for `$value` seconds and updating the list of results with `$value` diff --git a/challenge-143/james-smith/blog.txt b/challenge-143/james-smith/blog.txt new file mode 100644 index 0000000000..efff1b655b --- /dev/null +++ b/challenge-143/james-smith/blog.txt @@ -0,0 +1 @@ +https://github.com/drbaggy/perlweeklychallenge-club/new/master/challenge-143/james-smith diff --git a/challenge-143/james-smith/perl/ch-1.pl b/challenge-143/james-smith/perl/ch-1.pl new file mode 100644 index 0000000000..a4abfdeaab --- /dev/null +++ b/challenge-143/james-smith/perl/ch-1.pl @@ -0,0 +1,35 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; +use Benchmark qw(cmpthese timethis); +use Data::Dumper qw(Dumper); + +my @TESTS = ( + [ '10 + 20 - 5', 25 ], + [ '(10 + 20 - 5) * 2', 50 ], + [ '(5 - 10) * -5', 25 ], + [ '10 * 10 - 6 * 6 - 8 * 8', 0 ], + [ '4 + 4 - 6 - 2', 0 ], + [ '(10 + 10) * (10 - 10) * (10 + 10) * (20 - (((20))))', 0 ], +); + +is( evaluate($_->[0]), $_->[1] ) foreach @TESTS; +is( eval( $_->[0]), $_->[1] ) foreach @TESTS; +cmpthese( 20000, { + 'evaluate' => sub { evaluate($_->[0]) for @TESTS }, + 'eval' => sub { eval( $_->[0]) for @TESTS }, +}); +done_testing(); + +sub evaluate { + my $str = shift; + 1 while $str =~ s/\(\s*([^()]*?)\s*\)/ evaluate($1) /e; + 1 while $str =~ s/(-?\d+)\s*\*\s*(-?\d+)/ $1 * $2 /e; + 1 while $str =~ s/(-?\d+)\s*([-+])\s*(-?\d+)/$2 eq '+' ? $1+$3 : $1-$3/e; + return $str; +} + diff --git a/challenge-143/james-smith/perl/ch-2.pl b/challenge-143/james-smith/perl/ch-2.pl new file mode 100644 index 0000000000..ddfe30d376 --- /dev/null +++ b/challenge-143/james-smith/perl/ch-2.pl @@ -0,0 +1,33 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; +use Benchmark qw(cmpthese timethis); +use Data::Dumper qw(Dumper); + +my @ST = (4,12,24,36,40,60,72,84,112,120,144,180,220,240, + 252,264,312,336,360,364,400,420,432,480,504,540, + 544,600,612,660,672,684,760,792,840,864,900,924, + 936,1012,1080,1092,1104,1120,1200,1260,1300,1320); +my @NST = map { $_ + 15 } @ST; +my @TESTS = ( + [ 36, 1 ], + [ 12, 1 ], + [ 6, 0 ], + ( map { [$_ => 1] } @ST ), + ( map { [$_ => 0] } @NST ), +); + +is( stealthy_number($_->[0]), $_->[1] ) foreach @TESTS; + +done_testing(); + +sub stealthy_number { + my($n,%c) = shift; + $n%$_||($c{$n/$_+$_ }++,$c{$n/$_+$_+1}++) for 1..sqrt$n; + (grep { $_ > 1 } values %c) ? 1 : 0; +} + |
