Hello Jacinta,

Perl6 code should be much simpler than what you are trying. There is no need to use a state variable or a binding.

I'm not sure how to use a maximum in the sequence, so I didn't.

The Fibonacci sequence can be generated in a single line as

1, 1, &[+] ... *

or as
1, 1, *+* ... *
in your code.

So the question is how to apply your constraints, viz. a certain number of terms or a maximum.

The best thing when trying to experiment with perl6 is to use REPL, which you get by just typing perl6 in to a terminal.
Below is my output; my terminal gives me ">" to say its waiting for input

So
$ perl6
> say (1, 1, &[+] ... *)[0 .. 20]
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946

The Fibonacci sequence is in the () and the [0..20] gives me the first 21 values

By the way I tried just
say 1, 1, &[+] ... *
and the terminal hung. Got to put a stop on the sequence.

Now we need to get terms to a maximum, and you wanted to use gather/take, so

> say gather for 1, 1, &[+] ... * { last if $_ > 20000; take $_ }
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711

The sequence is after the 'for' and the test is inside the {}, with 'take' snapping up all values of the sequence that pass the filter

> say (gather for 1, 1, &[+] ... * { last if $_ > 20000; take $_ })[0 .. 19]
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765

This puts the two idioms together, implementing a maximum value of 20000 and a maximum number of terms.

You could avoid the magic $_ with a pointy block, eg.
gather for 1, 1, &[+] ... * -> $s { last if $s > 20000; take $s }

but I'm an old perl fan and I like the default variable $_ .

You want it in a subroutine?

> sub Fib ( :$max-value, :$max-no-terms ) {( gather for 1, 1, &[+] ... * -> $s { last if $s > $max-value; take $s } )[0 .. $max-no-terms] }
sub Fib(:max-value(:$max-value), :max-no-terms(:$max-no-terms)) { ... }

> say Fib(:max-no-terms(35),:max-value(20000) )
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711

Note that Fib uses named parameters, not positional parameters. See the : in the definition line.

Also notice how the named parameters were passed as pairs :xxx(yyy) when calling Fib. The = sign was not used.

Also no need to use an explicit return, because the value of a block is the value of the last line in the block, which in the Fib sub is truncated gather.

There is probably a shorter way. But the fundamental thing is the way to code the Fibonacci sequence.

Hope this helps.


Richard

On 12/12/2013 11:05 AM, Jacinta Richardson wrote:
G'day folk,

I'm slowing working through some basic exercises to get a feel for Perl 6. I'm currently trying to create a fibonacci sequence stopping at a maximum value, or a set number of terms...

I've written this:

    use v6;

    sub MAIN($terms = 35, $maximum = 4_000_000) {
        my @sequence = gather for fibonacci($maximum) -> $number {
            state $count = 0;
            take $number if $number < $maximum && $count++ < $terms;
        };

        say @sequence;
    }

    sub fibonacci($maximum) {
       my @numbers := 0, 1, *+* ... * < $maximum;
       return @numbers;
    }

with the sequence generator kindly inspired by http://justrakudoit.wordpress.com/2010/12/29/perl-6-fibonacci-versus-haskell/ but I can't get this to compile. The syntax highlighter is telling me something's wrong because say @sequence is all blue, instead of say appearing as a keyword, and the compiler says

===SORRY!===
Confused at line 19, near "}\n\nsub fib"

It's obvious I've done something wrong, but I just can't work out what it is. Can someone show me that which will be more obvious to me when I know more Perl 6?

Thanks,

    Jacinta


Reply via email to