diff options
| author | dasJake <no_mail@github.com> | 2021-12-01 23:28:15 +0100 |
|---|---|---|
| committer | dasJake <no_mail@github.com> | 2021-12-01 23:28:15 +0100 |
| commit | c6217ae7427a88fc7d4ecf8daa6e5029b935c32f (patch) | |
| tree | 874c9faa6d3cbf77199efa9ae66e4db25e66f04b | |
| parent | d9e173549d904ceb2da49185c33f071496a779c1 (diff) | |
| download | perlweeklychallenge-club-c6217ae7427a88fc7d4ecf8daa6e5029b935c32f.tar.gz perlweeklychallenge-club-c6217ae7427a88fc7d4ecf8daa6e5029b935c32f.tar.bz2 perlweeklychallenge-club-c6217ae7427a88fc7d4ecf8daa6e5029b935c32f.zip | |
141 add more performant method; still buggy
| -rwxr-xr-x | challenge-141/jake/perl/ch-1.pl | 71 |
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 |
