aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordasJake <no_mail@github.com>2021-12-01 23:28:15 +0100
committerdasJake <no_mail@github.com>2021-12-01 23:28:15 +0100
commitc6217ae7427a88fc7d4ecf8daa6e5029b935c32f (patch)
tree874c9faa6d3cbf77199efa9ae66e4db25e66f04b
parentd9e173549d904ceb2da49185c33f071496a779c1 (diff)
downloadperlweeklychallenge-club-c6217ae7427a88fc7d4ecf8daa6e5029b935c32f.tar.gz
perlweeklychallenge-club-c6217ae7427a88fc7d4ecf8daa6e5029b935c32f.tar.bz2
perlweeklychallenge-club-c6217ae7427a88fc7d4ecf8daa6e5029b935c32f.zip
141 add more performant method; still buggy
-rwxr-xr-xchallenge-141/jake/perl/ch-1.pl71
1 files changed, 50 insertions, 21 deletions
diff --git a/challenge-141/jake/perl/ch-1.pl b/challenge-141/jake/perl/ch-1.pl
index e03638a082..ce8c9da777 100755
--- a/challenge-141/jake/perl/ch-1.pl
+++ b/challenge-141/jake/perl/ch-1.pl
@@ -6,11 +6,12 @@ use feature 'say';
# number attributes
# num specifies the lowest number to start analysis
-# div_required specifies for how many divisors we aiming at
+# div_required specifies for how many divisors we're aiming at
# output specifies how many numbers will be displayed
+# div_required and output_required can be adjusted as desired
my $num_atr = {
num => '1',
- div_required => '8',
+ div_required => '6',
output_required => '10'
};
@@ -18,39 +19,67 @@ my $num_atr = {
my $res = collect_numbers();
say join (' ', @$res);
-
-
# aggregate required amount of numbers according to output_required
sub collect_numbers {
my @result = ();
while ( $#result+1 < $num_atr->{output_required} ) {
- push @result, count_divisors( $num_atr, 0, 0 );
+ push @result, count_divisors( $num_atr, 1 );
$num_atr->{num}++;
}
return \@result;
}
+# starting at 1 we aggregate all divisors in an array
+# we also aggregate all corresponding reciprocal values in another array
+# if these arrays are symmetric to each other at the position of half our's div_required, we know they have the required amount of divisors
+# p.e. num = 24; div_required = 8; the divisor arrays are cross-symmetric at div_required / 2
+# <==\\==>
+# 24 12 8 6\\4 3 2 1
+# 1 2 3 4\\6 8 12 24
+# <==\\==>
sub count_divisors {
- my ( $spec_num, $div_cntr, $subtractor) = @_;
+ my ( $spec_num, $divisor) = @_;
-# divide num through all numbers <= num and count every time modulo is 0
-# each time modulo is 0 we know it's a divisor
- while ( $subtractor != $num_atr->{num} ) {
- $div_cntr++ if $num_atr->{num} % ( $num_atr->{num} - $subtractor ) == 0;
- $subtractor++;
- }
+ # each iteration needs a fresh set of arrays
+ my @divisors = ();
+ my @reciprocal = ();
-# only return to sub collect_numbers if we hit the required amount of divisors
- if ( $div_cntr == $num_atr->{div_required} ) {
- return $num_atr->{num};
- }
+ # in case our divisor gets as large as our number, we stop aggregating our arrays
+ # because then we have arrived at the largest and smallest divisors
+ while ( $num_atr->{num} / $divisor >= 1 ) {
+
+ # finding our divisors
+ if ( $num_atr->{num} % $divisor == 0 ) {
+ push @divisors, $divisor;
+ push @reciprocal, ( $num_atr->{num} / $divisor );
+ }
-# when ever the current num did not meet the required divisors we need to start over counting them for the next num
-# in this case we must not return num to sub collect_numbers
- else {
- $num_atr->{num}++;
- return count_divisors( $num_atr, 0, 0 );
+ # if div_required is even
+ if ( $num_atr->{div_required} % 2 == 0 ) {
+ return $num_atr->{num} if $divisors[$num_atr->{div_required} / 2] && $divisors[$num_atr->{div_required} / 2] == $reciprocal[$num_atr->{div_required} / 2 - 1];
+ }
+
+ # if div_required is odd; CAPUTTED: ref massacre
+ #if ( $num_atr->{div_required} % 2 == 1 ) {
+ # return $num_atr->{num} if $divisors[int($num_atr->{div_required} / 2) + 1]
+ # && $divisors[int($num_atr->{div_required} / 2) + 1] == $reciprocal[int($num_atr->{div_required} / 2) + 1];
+ #}
+ if ( $num_atr->{div_required} % 2 == 1 ) {
+ return $num_atr->{num} if $divisors[3]
+ && $divisors[3] == $reciprocal[3];
+ }
+ #say ("line $num_atr->{div_required}");
+ #say[int($num_atr->{div_required} / 2) + 1];
+ #say $divisors[int($num_atr->{div_required} / 2) + 1];
+ #say $reciprocal[int($num_atr->{div_required} / 2) + 1];
+ #die if $num_atr->{num}==15;
+ $divisor++;
}
+
+ # when ever the current num did not meet the required divisors we need to start over counting them for the next num
+ # in this case we must not return num to sub collect_numbers
+ $num_atr->{num}++;
+ return count_divisors( $num_atr, 1 );
} \ No newline at end of file