aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-143/james-smith/README.md29
-rw-r--r--challenge-143/james-smith/blog.txt1
-rw-r--r--challenge-143/james-smith/perl/ch-1.pl35
-rw-r--r--challenge-143/james-smith/perl/ch-2.pl33
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;
+}
+