aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-195/wlmb/blog.txt1
-rwxr-xr-xchallenge-195/wlmb/perl/ch-1.pl48
-rwxr-xr-xchallenge-195/wlmb/perl/ch-2.pl10
3 files changed, 59 insertions, 0 deletions
diff --git a/challenge-195/wlmb/blog.txt b/challenge-195/wlmb/blog.txt
new file mode 100644
index 0000000000..a8e038bba3
--- /dev/null
+++ b/challenge-195/wlmb/blog.txt
@@ -0,0 +1 @@
+https://wlmb.github.io/2022/12/12/PWC195/
diff --git a/challenge-195/wlmb/perl/ch-1.pl b/challenge-195/wlmb/perl/ch-1.pl
new file mode 100755
index 0000000000..d131e286e3
--- /dev/null
+++ b/challenge-195/wlmb/perl/ch-1.pl
@@ -0,0 +1,48 @@
+#!/usr/bin/env perl
+# Perl weekly challenge 195
+# Task 1: Special Integers
+#
+# See https://wlmb.github.io/2022/12/12/PWC195/#task-1-special-integers
+use v5.36;
+use integer;
+use POSIX qw(lround);
+say(<<"FIN"), exit unless @ARGV;
+Usage: $0 N1 [N2...]
+to get the number of special numbers between 1 and Ni
+FIN
+say "$_->", special($_) for @ARGV;
+sub fact($n){ # factorial
+ my $r=1;
+ $r*=$_ for (1..$n);
+ $r
+}
+sub special($n){
+ my $k=0;
+ my $count=0;
+ while($k<=9 && 10**($k+1) < $n){
+ # Count from 1 to 9, then from 10 to 99, then from 100 to 999, etc.
+ $count += 9*fact(9)/fact(9-$k);
+ ++$k;
+ }
+ return $count if $k>9; # Nothing else to do eleven digit numbers or larger
+ #Count from 100.. to q00..-1
+ my $q=lround($n/10**$k);
+ $count += ($q-1)*fact(9)/fact(9-$k);
+ $count += final($q, $k-1, $n); # count from q00... upto $n=qxy...
+ return $count;
+}
+sub final($left, $power, $n){ # final approach from left 0 0 0 to n=x y z
+ my $count=0;
+ my $fixed=length $left; # leftward fixed digits
+ my %fixed;
+ ++$fixed{$_} for my @fixed=split '', $left; # actual fixed digits.
+ $_>1 && return 0 for(values %fixed); # nothing to add if fixed part is not special
+ return 1 if $power < 0; # Found last string
+ my $target=substr($n, $fixed, 1); # Next digit
+ for(0..$target-1){ # count upwards to target
+ next if $fixed{$_}; # skip seen digits
+ $count += fact(9-$fixed)/fact(9-$fixed-$power); # add rightwards contribution
+ }
+ $count += final($left.$target, $power-1, $n); # add digit to leftmost and recurse.
+ return $count;
+}
diff --git a/challenge-195/wlmb/perl/ch-2.pl b/challenge-195/wlmb/perl/ch-2.pl
new file mode 100755
index 0000000000..c4dfa29c27
--- /dev/null
+++ b/challenge-195/wlmb/perl/ch-2.pl
@@ -0,0 +1,10 @@
+#!/usr/bin/env perl
+# Perl weekly challenge 195
+# Task 2: Most Frequent Even
+#
+# See https://wlmb.github.io/2022/12/12/PWC195/#task-2-most-frequent-even
+use v5.36;
+my %count;
+$count{$_}++ for grep {!($_&1)} @ARGV; # Filter evens and count them
+my @sorted=sort {$count{$b} <=> $count{$a} || $a<=>$b} keys %count;
+say join " ", @ARGV, " -> ", @sorted?shift @sorted:-1