Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Can't call method "forprimes"

by pvfki (Novice)
on Jul 15, 2019 at 06:13 UTC ( [id://11102846]=perlquestion: print w/replies, xml ) Need Help??

pvfki has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I've been running the following code below and get the following errors:
#!/usr/bin/env perl use warnings; use strict; use ntheory; use bigint; my $n=12; my $c=1; my $k=10; my $l=10; my $p=100; my @candidates = (0..$l); my $remove; sieve2(); sub sieve2 { forprimes { $p=$_; foreach my $i (0..$l) { if ( ($n*($k+$i)+$c)%$p==0) { $remove=$i; @candidates = grep {!/$remove/} @candidates; } } } print join("\n",@candidates),"\n"; } sieve2();
Errors:
C:\Users\Perl Scripts> sieve2.pl Use of uninitialized value in new at C:\Users\Paul\Documents\Perl Scri +pts\question.pl line 20. Use of uninitialized value in new at C:\Users\Paul\Documents\Perl Scri +pts\question.pl line 20. Use of uninitialized value in new at C:\Users\Paul\Documents\Perl Scri +pts\question.pl line 20. Use of uninitialized value in new at C:\Users\Paul\Documents\Perl Scri +pts\question.pl line 20. Use of uninitialized value in new at C:\Users\Paul\Documents\Perl Scri +pts\question.pl line 20. Use of uninitialized value in new at C:\Users\Paul\Documents\Perl Scri +pts\question.pl line 20. Use of uninitialized value in new at C:\Users\Paul\Documents\Perl Scri +pts\question.pl line 20. Use of uninitialized value in new at C:\Users\Paul\Documents\Perl Scri +pts\question.pl line 20. Use of uninitialized value in new at C:\Users\Paul\Documents\Perl Scri +pts\question.pl line 20. Use of uninitialized value in new at C:\Users\Paul\Documents\Perl Scri +pts\question.pl line 20. Use of uninitialized value in new at C:\Users\Paul\Documents\Perl Scri +pts\question.pl line 20. 0 1 2 3 4 5 6 7 8 9 10 Can't call method "forprimes" without a package or object reference at + C:\Users\Paul\Documents\Perl Scripts\question.pl line 18.
So I know that I've included the right dependencies for forprimes (the exact function is right here: https://metacpan.org/pod/ntheory#forprimes) so I don't see what I'm doing wrong. To be more specific about the code: Given integers n, c, k, l, and p, sieves all numbers of the form n*(k+i)+c where 0 <= i <= l up to all primes less than p. So in my program example where I chose parameters 12, 1, 10, 10, and 100 respectively, the correct output should be:
3 5 6 9 10
Any ideas of how to obtain this? Thanks for help in advance!

Replies are listed 'Best First'.
Re: Can't call method "forprimes"
by Athanasius (Archbishop) on Jul 15, 2019 at 07:01 UTC

    Hello pvfki,

    Your script has a number of problems:

    • The forprimes function must be explicitly imported: e.g., use ntheory 'forprimes';.
    • forprimes takes a block followed by either 1 or 2 integers.
    • Within the block, the current prime is assigned to $_ ($p always remains 100).
    • In the expression grep {!/$remove/} @candidates the regex matches any string containing the characters in $remove. So, e.g., if $remove is 1 then the regex will match 10. To fix this, you can add a beginning-of-string and an end-of-string assertion: grep {!/^$remove$/} .... However, it’s simpler to use != here: grep { $_ != $remove } @candidates.
    • There is no real point in calling sieve2() twice. Since you don’t pass @candidates into the function, it will be set by the first call and unchanged by subsequent calls.

    I think the following code is what you’re looking for:

    use warnings; use strict; use ntheory 'forprimes'; use bigint; my $n = 12; my $c = 1; my $k = 10; my $l = 10; my $p = 100; my @candidates = (0 .. $l); my $remove; sieve2(); sub sieve2 { forprimes { for my $i (0 .. $l) { if (($n * ($k + $i) + $c) % $_ == 0) { $remove = $i; @candidates = grep { $_ != $remove } @candidates; } } } $p; print join("\n", @candidates),"\n"; }

    Output:

    16:58 >perl 2012_SoPW.pl 3 5 6 9 10 16:58 >

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      It took me a solid 10 Minutes to parse the logic of that inner block. In german we have an expression for that: Von hinten durch die Brust ins Auge. Consider the following code, I think it makes the intention much clearer and it doesn't use globals.
      use Modern::Perl; use Sub::Signatures; use ntheory 'primes'; use bigint; print join "*", sieve3( 12, 1, 10, 10, 100 ); sub sieve3 ( $n, $c, $k, $l, $p ) { my %candidates = map { $_ => $n * ( $k + $_ ) + $c } ( 0 .. $l ); foreach my $prime ( @{primes $p} ) { foreach my $candidate ( keys %candidates ) { delete $candidates{$candidate} if defined $candidates{$candidate} && $candidates{$can +didate} % $prime == 0; } } return sort { $a <=> $b } keys %candidates; }


      holli

      You can lead your users to water, but alas, you cannot drown them.
Re: Can't call method "forprimes"
by holli (Abbot) on Jul 15, 2019 at 07:04 UTC
    You need to import the subroutine

    use ntheory qw( forprimes );

    But even then you're using it wrong. The syntax is
    forprimes { say } 100,200; # print primes from 100 to 200 forprimes { say } 100; # print primes from 0 to 100


    holli

    You can lead your users to water, but alas, you cannot drown them.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11102846]
Approved by Athanasius
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (6)
As of 2024-04-23 15:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found