Clever!

I had missed checking "is-prime" straight away! Checked some large primes, and my function hung badly. Thank you!

Is grep running on all "2 ..^ $n/2" values, and then picking the first, or is that somehow lazily evaluated? I assume the former, or you'd have no need to halve $n. But I don't see any definitive speed increase either way.

What factors (pun un-intended) lead you to gather/take? I've not used it much, so I don't have much of a feel for its strengths over other control flows.

I also need to pay more attention to while's "recursive" abilities, if that's the proper word for it. Seems to fit well with gather/take. No explicit returns!

- Rick


On 6/17/22 02:04, Simon Proctor wrote:
Here's my new go to prime-factors function :

sub prime-factors( Int $n is copy where * > 1 ) {
     gather {
         while ( $n > 1 ) {
             if ( $n.is-prime ) {
                 take $n;
                 last;
             }
             my $f = (2..^$n/2).grep($n %% *).first(*.is-prime);
             take $f;
             $n = $n div $f
         }
     }
}

On Fri, 17 Jun 2022 at 03:51, Simon Proctor <simon.proc...@gmail.com <mailto:simon.proc...@gmail.com>> wrote:

    This is because if there isn't an explicit return the last statement
    evaluated is the implied return value.

    So the last call (which returns Nil) was your implicit return.

    Generally I try and avoid an implicit return if a function has more
    than a couple of lines.

    On Thu, 16 Jun 2022, 21:41 Rick Bychowski, <r...@hiranyaloka.com
    <mailto:r...@hiranyaloka.com>> wrote:

        For example here:

        
https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-168/rick-bychowski/raku/ch-2.raku
        
<https://github.com/manwar/perlweeklychallenge-club/blob/master/challenge-168/rick-bychowski/raku/ch-2.raku>

        I called the recursive function at various points in an if/else
        statement, but each call was always the very last statement of the
        branch/routine. Otherwise, even a trailing "last" or "exit"
        silently
        "fails".

        All good!

        - Rick

        On 6/16/22 13:21, Rick Bychowski wrote:
         > Yep, the "return factors($q, @f)" fixes it. I've not called a
        recursion
         > from anywhere other than the end of a routine, so haven't run
        into this
         > issue before. Learned something today!
         >
         > Thanks to Simon, William and Andinus for your assistance!
         >
         > - Rick
         >
         > On 6/16/22 11:07, Simon Proctor wrote:
         >> I think, and I don't have my computer to hand to double
        check but I
         >> think you want a return before your recursive.call to
        factors passing
         >> in @f.
         >>
         >> When dealing with recursive functions you need to make sure
        what
         >> you're returning back up the stack.
         >>
         >>
         >>
         >> On Thu, 16 Jun 2022, 18:10 Rick Bychowski,
        <r...@hiranyaloka.com <mailto:r...@hiranyaloka.com>
         >> <mailto:r...@hiranyaloka.com <mailto:r...@hiranyaloka.com>>>
        wrote:
         >>
         >>     Hi Everyone,
         >>
         >>     I've been lurking quite a while, this will be my first
        post to perl6
         >>     users. I've written a lot of short scripts in perl5 for
        system admin
         >>     type stuff at home and work. Lately I'm playing with
        Raku, which is a
         >>     lot of fun. Error reporting is excellent, as is the online
         >>     documentation.
         >>
         >>     To the point. I recently started the perl weekly
        challenge. Lots of
         >>     math/primes stuff. I wrote an algorithm to list all the
        prime
         >>     factors of
         >>     an integer, using a recursive subroutine. I'm able to
        print the
         >> result
         >>     from the subroutine, but it always returns Nil. What am
        I missing?
         >>
         >>     #!/usr/bin/env raku
         >>
         >>     sub MAIN($n = 20) {
         >>          .say for factors($n); # Nil
         >>     }
         >>
         >>     sub factors($n, @factors?) {
         >>           my @f = @factors.elems ?? @factors !! ();
         >>           my $q;
         >>           for 2 ..^ $n -> $i {
         >>               if $n %% $i {
         >>                   $q = Int($n / $i);
         >>                   @f.push($i);
         >>                   if $q.is-prime {
         >>                       @f.push($q);
         >>                       say @f;    # [2 2 5]
         >>                       return @f;
         >>                   } else {
         >>                       factors($q, @f);
         >>                   }
         >>                   last;
         >>               }
         >>           }
         >>     }
         >>
         >>     Returns
         >>     [2 2 5]
         >>     Nil
         >>
         >>     --     Rick Bychowski
         >>
         >>     The information in this email is confidential and may be
        legally
         >>     privileged. It is intended solely for the addressee(s).
        Access to
         >> this
         >>     e-mail by anyone else is unauthorized.
         >>
         >

-- Rick Bychowski

        The information in this email is confidential and may be legally
        privileged. It is intended solely for the addressee(s). Access
        to this
        e-mail by anyone else is unauthorized.



--
Simon Proctor
Cognoscite aliquid novum cotidie

http://www.khanate.co.uk/ <http://www.khanate.co.uk/>

--
Rick Bychowski

The information in this email is confidential and may be legally privileged. It is intended solely for the addressee(s). Access to this e-mail by anyone else is unauthorized.

Reply via email to