aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2023-03-10 21:43:52 +0000
committerGitHub <noreply@github.com>2023-03-10 21:43:52 +0000
commit2dfb0bc1a3779d88d7fc6fa881ba0187b1b3f38a (patch)
tree45a52a7e31b030f485337f825868d8244ab00145
parentf2e33c0038917ad43651d0c4e8b0bb310eaed541 (diff)
parent7c25bd7c2f37595d67c2e37723a6aca650bc216f (diff)
downloadperlweeklychallenge-club-2dfb0bc1a3779d88d7fc6fa881ba0187b1b3f38a.tar.gz
perlweeklychallenge-club-2dfb0bc1a3779d88d7fc6fa881ba0187b1b3f38a.tar.bz2
perlweeklychallenge-club-2dfb0bc1a3779d88d7fc6fa881ba0187b1b3f38a.zip
Merge pull request #7698 from boblied/master
Backlog week 176
-rw-r--r--challenge-176/bob-lied/README4
-rw-r--r--challenge-176/bob-lied/blog.txt1
-rw-r--r--challenge-176/bob-lied/perl/ch-1.pl73
-rw-r--r--challenge-176/bob-lied/perl/ch-2.pl55
-rw-r--r--challenge-176/bob-lied/perl/rev.c61
-rw-r--r--challenge-176/bob-lied/perl/rev.pl69
6 files changed, 261 insertions, 2 deletions
diff --git a/challenge-176/bob-lied/README b/challenge-176/bob-lied/README
index c231e3a589..a6a80e8eea 100644
--- a/challenge-176/bob-lied/README
+++ b/challenge-176/bob-lied/README
@@ -1,3 +1,3 @@
-Solutions to weekly challenge 138 by Bob Lied
+Solutions to weekly challenge 176 by Bob Lied
-https://perlweeklychallenge.org/blog/perl-weekly-challenge-138/
+https://perlweeklychallenge.org/blog/perl-weekly-challenge-176/
diff --git a/challenge-176/bob-lied/blog.txt b/challenge-176/bob-lied/blog.txt
new file mode 100644
index 0000000000..234f398ef6
--- /dev/null
+++ b/challenge-176/bob-lied/blog.txt
@@ -0,0 +1 @@
+https://dev.to/boblied/pwc-176-reversing-a-number-39gg
diff --git a/challenge-176/bob-lied/perl/ch-1.pl b/challenge-176/bob-lied/perl/ch-1.pl
new file mode 100644
index 0000000000..2c663c5d77
--- /dev/null
+++ b/challenge-176/bob-lied/perl/ch-1.pl
@@ -0,0 +1,73 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# ch-1.pl Perl Weekly Challenge Week 176 Task 1 Permuted Multiples
+#=============================================================================
+# Copyright (c) 2023, Bob Lied
+#=============================================================================
+# Write a script to find the smallest positive integer x
+# such that x, 2x, 3x, 4x, 5x and 6x are permuted multiples of each other.
+# For example, the integers 125874 and 251748 are permutated multiples
+# of each other as 251784 = 2 x 125874
+# and also both have the same digits but in different order.
+# Output 142857
+#=============================================================================
+
+use v5.36;
+
+use builtin qw/true false/;
+no warnings "experimental::builtin";
+
+use List::Util qw/all/;
+
+use Getopt::Long;
+my $DoTest = false;
+my $DoAll = false;
+my $Size = 6;
+
+GetOptions("test" => \$DoTest, "all" => \$DoAll, "size:i" => \$Size);
+exit(!runTest()) if $DoTest;
+
+sub isPermutation($digits, $m)
+{
+ my @m = sort split("", $m);
+ return false if $#m != $#{$digits};
+ return all { $digits->[$_] == $m[$_] } 0 .. $#m;
+}
+
+say join(" ", smallestPermuted($Size, $DoAll)->@*);
+
+sub smallestPermuted($size = 6, $doAll = false)
+{
+ my @result;
+ MAG: for ( my $magnitude = 100 ; $magnitude <= 10**$size ; $magnitude *= 10 )
+ {
+ my $max = int( $magnitude / 6 );
+ my $base = int ( $max / 10 );
+ for ( my $i = $base + 1 ; $i <= $base + $max ; $i++ )
+ {
+ my @digits = sort split("", $i);
+
+ if ( all { isPermutation(\@digits, $i * $_) } 2 .. 6 )
+ {
+ push @result, $i;
+ last MAG unless $doAll;
+ }
+ }
+ }
+ return \@result;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( smallestPermuted(2), [], "2 digits");
+ is( smallestPermuted(3), [], "3 digits");
+ is( smallestPermuted(4), [], "4 digits");
+ is( smallestPermuted(5), [], "5 digits");
+ is( smallestPermuted(6), [ 142857 ], "6 digits");
+
+ done_testing;
+}
+
diff --git a/challenge-176/bob-lied/perl/ch-2.pl b/challenge-176/bob-lied/perl/ch-2.pl
new file mode 100644
index 0000000000..d59aabaeb0
--- /dev/null
+++ b/challenge-176/bob-lied/perl/ch-2.pl
@@ -0,0 +1,55 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# ch-2.pl Perl Weekly Challenge Task 2 Reversible Numbers
+#=============================================================================
+# Copyright (c) 2023, Bob Lied
+#=============================================================================
+# Write a script to find out all Reversible Numbers below 100.
+# A number is said to be a reversible if sum of the number and its
+# reverse had only odd digits.
+# For example,
+# 36 is reversible number as 36 + 63 = 99 i.e. all digits are odd.
+# 17 is not reversible as 17 + 71 = 88, none of the digits are odd.
+#=============================================================================
+
+use v5.36;
+
+use builtin qw/true false/;
+no warnings "experimental::builtin";
+
+# To be an odd number, it has to be the sum of an even and an odd number.
+# We're considering only two-digit numbers, so that means if the first digit
+# is odd, the second must be even, and vice versa. Generate the possibilities.
+my @candidate = ( glob("{1,3,5,7,9}{0,2,4,6,8}"), glob("{2,4,6,8}{1,3,5,7,9}") );
+
+say join ",", sort { $a <=> $b }
+ grep { $_ < 100 && allOdd($_ + revNum($_)) } @candidate;
+
+# There are two fairly obvious ways of reversing the number. We can treat
+# it as a string and reverse the digits, or we can do the math. The string
+# operations are actually faster.
+sub revNum($n)
+{
+ (my $r = reverse("$n")) =~ s/^0+//;
+ return +($r);
+}
+
+# Checking that all digits are odd. Again, two possibilities: do the math
+# one digit at a time, or treat as a string and test each digit.
+sub allOdd($n)
+{
+ my $isOdd = true; # Doesn't handle 0, but 0 is not happening here.
+ while ( $n && $isOdd )
+ {
+ $isOdd &&= ( $n % 10 ) % 2;
+ $n = int($n / 10);
+ }
+ return $isOdd;
+}
+
+sub allOdd_str($n)
+{
+ use List::Util qw/all/;
+ return all { $_ % 2 } split("", $n);
+}
diff --git a/challenge-176/bob-lied/perl/rev.c b/challenge-176/bob-lied/perl/rev.c
new file mode 100644
index 0000000000..0dff0ea4fb
--- /dev/null
+++ b/challenge-176/bob-lied/perl/rev.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <time.h>
+
+void reverse(char s[])
+{
+ int i, j;
+ char c;
+
+ for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
+ c = s[i];
+ s[i] = s[j];
+ s[j] = c;
+ }
+}
+
+int rev1(int n)
+{
+ int r = n % 10;
+ while ( (n = n / 10) != 0 )
+ {
+ r = r*10 + n % 10;
+ }
+ return r;
+}
+
+int rev2(int n)
+{
+ char s[16];
+ sprintf(s, "%d", n);
+ reverse(s);
+ return ( atoi(s) );
+}
+
+int main(int argc, char **argv)
+{
+ int r;
+
+ const int start = 123400000;
+ const int end = 123500000;
+
+ clock_t begin = clock();
+ for ( int n = start; n <= end; n++ )
+ {
+ r = rev1(n);
+ }
+ clock_t finish = clock();
+ double t = (double)(finish - begin) / CLOCKS_PER_SEC;
+ printf("rev numeric %d %f\n", r, t);
+
+ begin = clock();
+ for ( int n = start; n <= end; n++ )
+ {
+ r = rev2(n);
+ }
+ finish = clock();
+ t = (double)(finish - begin) / CLOCKS_PER_SEC;
+ printf("rev string %d %f\n", r, t);
+}
diff --git a/challenge-176/bob-lied/perl/rev.pl b/challenge-176/bob-lied/perl/rev.pl
new file mode 100644
index 0000000000..349c96cd1a
--- /dev/null
+++ b/challenge-176/bob-lied/perl/rev.pl
@@ -0,0 +1,69 @@
+#!/usr/bin/env perl
+# vim:set ts=4 sw=4 sts=4 et ai wm=0 nu:
+#=============================================================================
+# rev.pl
+#=============================================================================
+# Copyright (c) 2023, Bob Lied
+#=============================================================================
+# We need to reverse a number (e.g, 632 -> 236). Which is faster: doing
+# the math, or treating it as a string?
+#=============================================================================
+
+use v5.36;
+
+use Benchmark qw/cmpthese/;
+
+use Getopt::Long;
+my $DoBenchmark = 0;
+my $DoTest = 0;
+
+GetOptions("test" => \$DoTest, "benchmark" => \$DoBenchmark);
+
+if ( $DoBenchmark )
+{
+ cmpthese(-5, {
+ numeric => sub {
+ rev1($_) for 123400 .. 124500;
+ },
+ string => sub {
+ rev2($_) for 123400 .. 124500;
+ },
+ }
+ );
+}
+exit(!runTest()) if $DoTest;
+
+sub rev1($n)
+{
+ use integer;
+ my $r = $n % 10;
+ while ( $n = int($n/10) )
+ {
+ $r = ($r * 10) + ($n % 10);
+ }
+ return $r;
+}
+
+sub rev2($n)
+{
+ (my $r = reverse("$n")) =~ s/^0+//;
+ return $r;
+}
+
+sub runTest
+{
+ use Test2::V0;
+
+ is( rev1( 2), 2, "Test 1");
+ is( rev1( 20), 2, "Test 2");
+ is( rev1(632), 236, "Test 3");
+ is( rev1(495632), 236594, "Test 6");
+
+ is( rev2( 2), 2, "Test 1");
+ is( rev2( 20), 2, "Test 2");
+ is( rev2(632), 236, "Test 3");
+ is( rev2(495632), 236594, "Test 6");
+
+ done_testing;
+}
+