aboutsummaryrefslogtreecommitdiff
path: root/challenge-141
diff options
context:
space:
mode:
authorJörg Sommrey <28217714+jo-37@users.noreply.github.com>2021-11-29 21:20:19 +0100
committerJörg Sommrey <28217714+jo-37@users.noreply.github.com>2021-12-03 19:31:33 +0100
commit9371cac1f25447d91158e48c44de5fde9e4b31bc (patch)
tree504863168939bf8bf9aa04d1c94cc0da286db9d4 /challenge-141
parent873d87e5709a4abe371aab03c195ea116449886b (diff)
downloadperlweeklychallenge-club-9371cac1f25447d91158e48c44de5fde9e4b31bc.tar.gz
perlweeklychallenge-club-9371cac1f25447d91158e48c44de5fde9e4b31bc.tar.bz2
perlweeklychallenge-club-9371cac1f25447d91158e48c44de5fde9e4b31bc.zip
Solution to task 2
Diffstat (limited to 'challenge-141')
-rwxr-xr-xchallenge-141/jo-37/perl/ch-2.pl76
1 files changed, 76 insertions, 0 deletions
diff --git a/challenge-141/jo-37/perl/ch-2.pl b/challenge-141/jo-37/perl/ch-2.pl
new file mode 100755
index 0000000000..e421d42f94
--- /dev/null
+++ b/challenge-141/jo-37/perl/ch-2.pl
@@ -0,0 +1,76 @@
+#!/usr/bin/perl -s
+
+use v5.16;
+use Test2::V0;
+use Math::Prime::Util qw(todigits fromdigits);
+use List::MoreUtils 'indexes';
+use experimental 'signatures';
+
+our ($tests, $examples, $verbose);
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV;
+usage: $0 [-examples] [-tests] [-verbose] [M N]
+
+-examples
+ run the examples from the challenge
+
+-tests
+ run some tests
+
+-verbose
+ print the found numbers instead of the count thereof
+
+M N
+ find integers created by M divisible by N
+
+EOS
+
+
+### Input and Output
+
+main: {
+ my @like_num = like_num(@ARGV);
+ say $verbose ? "@like_num" : scalar @like_num;
+}
+
+
+### Implementation
+
+# Take the indices of 1-bits in the binary representation of the numbers
+# from 1 to 2 ** length($m) - 2 (representing all valid subsequences) as
+# slice arguments for the decimal digits of $m and collect all results
+# divisible by $n. Return the found unique numbers.
+sub like_num ($m, $n) {
+ my @digits = todigits $m;
+ my %divisible;
+ @divisible{
+ grep !($_ % $n),
+ map fromdigits([@digits[indexes {$_} todigits $_, 2, @digits]]),
+ 1 .. 2 ** @digits - 2
+ } = ();
+
+ keys %divisible;
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip "examples" unless $examples;
+ is scalar(like_num(1234, 2)), 9, 'example 1';
+ is scalar(like_num(768, 4)), 3, 'example 2';
+ }
+
+ SKIP: {
+ skip "tests" unless $tests;
+ is scalar(like_num(135, 2)), 0, 'no even subnumber';
+ is scalar(like_num(12345, 1)), 2**5 - 2, 'count valid subnumbers';
+ is scalar(like_num(2222, 2)), 3, 'count numbers only once';
+ }
+
+ done_testing;
+ exit;
+}