aboutsummaryrefslogtreecommitdiff
path: root/challenge-149
diff options
context:
space:
mode:
authorNiels van Dijke <65567640+PerlBoy1967@users.noreply.github.com>2022-01-31 00:10:47 +0100
committerGitHub <noreply@github.com>2022-01-31 00:10:47 +0100
commitf951e4dad8d9c70fd007fe4b76e674c20ae52afe (patch)
tree9144857662071238964a6b8057244f4711264de6 /challenge-149
parente4ce02136d00f540a9b291d02e78c1b4ef503ccc (diff)
downloadperlweeklychallenge-club-f951e4dad8d9c70fd007fe4b76e674c20ae52afe.tar.gz
perlweeklychallenge-club-f951e4dad8d9c70fd007fe4b76e674c20ae52afe.tar.bz2
perlweeklychallenge-club-f951e4dad8d9c70fd007fe4b76e674c20ae52afe.zip
Create ch-2.pl
Diffstat (limited to 'challenge-149')
-rw-r--r--challenge-149/perlboy1967/perl/ch-2.pl72
1 files changed, 72 insertions, 0 deletions
diff --git a/challenge-149/perlboy1967/perl/ch-2.pl b/challenge-149/perlboy1967/perl/ch-2.pl
new file mode 100644
index 0000000000..fc02a823ca
--- /dev/null
+++ b/challenge-149/perlboy1967/perl/ch-2.pl
@@ -0,0 +1,72 @@
+#!/bin/perl
+
+=pod
+
+The Weekly Challenge - 149
+ - https://perlweeklychallenge.org/blog/perl-weekly-challenge-149/#TASK2
+
+Author: Niels 'PerlBoy' van Dijke
+
+TASK #2 › Largest Square
+Submitted by: Roger Bell_West
+
+Given a number base, derive the largest perfect square with no repeated digits and return it as a string.
+(For base>10, use ‘A’..‘Z’.)
+
+=cut
+
+use v5.16;
+
+use bigint;
+use List::MoreUtils qw(duplicates);
+use POSIX qw(floor);
+
+sub convertBase10toBaseN($$);
+sub convertBaseNtoBase10($$);
+
+my @digits = (0 .. 9, 'A' .. 'Z');
+
+foreach my $base (2 .. 12) {
+ my $iSqrt = sqrt convertBaseNtoBase10(join('', reverse @digits[0 .. $base-1]), $base);
+
+ while ($iSqrt >= 1) {
+ my $nSqr = convertBase10toBaseN($iSqrt * $iSqrt, $base);
+
+ if (!duplicates(split//, $nSqr)) {
+ say "f($base) = $nSqr";
+ last;
+ }
+
+ $iSqrt--;
+ }
+}
+
+sub convertBase10toBaseN ($$) {
+ my ($n, $base) = @_;
+
+ state $digits = [@digits];
+
+ my @nMod; my %nMod;
+
+ while ($n) {
+ push(@nMod, $n % $base);
+ $nMod{$nMod[-1]}++;
+ $n = floor($n/$base); # Use floor instead of int(..) for performance
+ }
+
+ return join('', reverse map {$digits->[$_]} @nMod);
+}
+
+sub convertBaseNtoBase10 ($$) {
+ my ($n, $base) = @_;
+
+ my ($res, $i) = (0, 0);
+ state $digits = { map { ($_, $i++) } (@digits) };
+
+ $i = 0;
+ foreach (reverse split //, $n) {
+ $res += $digits->{uc$_} * ($base**$i++);
+ }
+
+ return $res;
+}