develooper Front page | perl.perl6.users | Postings from September 2021

Re: [better solution] pairs of separators from a string

Thread Previous
From:
William Michels via perl6-users
Date:
September 20, 2021 16:19
Subject:
Re: [better solution] pairs of separators from a string
Message ID:
CAA99HCzN9V1L=9i3ONR3JjFEs_J12foB7w7Ryjmwzn05x++czA@mail.gmail.com
>>>>Search String: "I like (parens) and the Apple ][+" they said.

(above quote from the posted question).

Yary, you could have written that! --B.


On Mon, Sep 20, 2021 at 7:53 AM yary <not.com@gmail.com> wrote:
>
> See Challenge #2 in https://theweeklychallenge.org/blog/perl-weekly-challenge-131/ ... !
>
> -y
>
>
> On Wed, Aug 25, 2021 at 2:08 PM William Michels <wjm1@caa.columbia.edu> wrote:
>>
>> Hi Andy!
>>
>> Maybe this helps (separate coding elements with parens and/or brackets, still get the same result):
>>
>> > say 1, 1, * + * ...^ *>= 100;
>> (1 1 2 3 5 8 13 21 34 55 89)
>>
>> > say 1, 1, * + * ...^ (*>= 100);
>> (1 1 2 3 5 8 13 21 34 55 89)
>>
>> > say 1, 1, * + * ...^ ( * >= 100);
>> (1 1 2 3 5 8 13 21 34 55 89)
>>
>> > say (1, 1, * + *) ...^ ( * >= 100);
>> (1 1 2 3 5 8 13 21 34 55 89)
>>
>> > say 1, 1, * + * [...^] ( * >= 100);
>> (1 1 2 3 5 8 13 21 34 55 89)
>>
>> > say (1, 1, * + *) [...^] ( * >= 100);
>> (1 1 2 3 5 8 13 21 34 55 89)
>>
>> From Yary:
>> >> Ranges also support arbitrary functions, the doc page shows a Fibonacci number generator
>> >> https://docs.raku.org/language/operators#index-entry-sequence_operator
>>
>> The Fibonacci code above (and in the docs) uses the sequence operator (infix ...), not the range operator (infix ..). To recap for Andy: Yary, Vadim, Brian, Fernando and Marc have posted code using the sequence operator; I've previously posted code using the range operator coupled with a grep() call  [I recall reading somewhere that ranges are cheaper to construct than sequences, but can't locate the reference at the moment].
>>
>> FWIW_1, I was unable to get the Fibonacci code to work with the range operator:
>>
>> > say 1, 1, * + * ..^ *>= 100;
>> 11WhateverCode.new
>>
>> FWIW_2, I've had good luck grepping out composite sequences with the 'range_operator / grep' strategy:
>>
>> > #Using "(^*)" as a synonym for the range "(0..*-1)", see: https://docs.raku.org/type/Range
>> Nil
>>
>> > ( 0..11 ).[ (^*).grep: * %% 2 ]
>> (0 2 4 6 8 10)
>>
>> > ( 0..11 ).[ (^*).grep: * %% 3 ]
>> (0 3 6 9)
>>
>> > ( 0..11 ).[ (^*).grep: * %% (2|3) ]
>> (0 2 3 4 6 8 9 10)
>>
>> > ( 0..11 ).[ (^*).grep: * %% any(2,3) ]
>> (0 2 3 4 6 8 9 10)
>>
>> HTH, Bill.
>>
>> PS Now to try to understand the differences (shown earlier in this thread) when the := binding operator is used!
>>
>>
>> On Wed, Aug 25, 2021 at 7:15 AM Andy Bach <Andy_Bach@wiwb.uscourts.gov> wrote:
>>>
>>> I "misread"
>>> say 1, 1, * + * ...^ *>= 100;
>>>
>>> thinking "shouldn't it be '<=' as you want the total to be less than 100?" but
>>> $ raku -e 'say 1, 1, * + * ...^ *<= 100;'
>>> ===SORRY!=== Error while compiling -e
>>> Whitespace required before <= operator
>>> at -e:1
>>> ------> say 1, 1, * + * ...^ *<= 100;⏏<EOL>
>>>     expecting any of:
>>>         postfix
>>>
>>> and
>>> $ raku -e 'say 1, 1, * + * ...^ * <= 100;'
>>> ()
>>> $ raku -e 'say 1, 1, * + * ...^ * >= 100;'
>>> (1 1 2 3 5 8 13 21 34 55 89)
>>>
>>> So, then it dawned on me that the '>=' is "binding" (right word?) to the "*" marking the end of the sequence as "until I am ge 100".  Though that doesn't quite work,
>>> $ raku -e 'say 1, 1, * + * ...^ * <= 100;'
>>> ()
>>>
>>> Ah, I see, it does work. The end of the sequence is the first number less than 100, so 1 succeeds.  I guess the sequence never gets started.
>>> ________________________________
>>> From: yary <not.com@gmail.com>
>>> Sent: Tuesday, August 24, 2021 8:39 PM
>>> To: William Michels <wjm1@caa.columbia.edu>
>>> Cc: Marc Chantreux <eiro@phear.org>; raku-users <perl6-users@perl.org>
>>> Subject: Re: [better solution] pairs of separators from a string
>>>
>>> CAUTION - EXTERNAL:
>>>
>>> Hi Bill,
>>>
>>> When building a range that's an arithmetic or geometric progression, the sequence operator is a little quicker to type. And thus also more likely to be understood more quickly too.
>>>
>>> > ('a' .. 'h')[(0..*-1).grep: * %% 2 ]
>>> (a c e g)
>>> > ('a' .. 'h')[ 0, 2 ... * ]
>>> (a c e g)
>>>
>>> > ('a' .. 'h')[(0..*-1).grep: * % 2 ]
>>> (b d f h)
>>> > ('a' .. 'h')[1, 3...*]
>>> (b d f h)
>>>
>>> # Geometric example- powers of 2
>>> > ('a' .. 'z')[1, 2, 4...*]
>>> (b c e i q)
>>>
>>> There isn't a simple translation for the is-prime example that I can think of, that is a good use for "grep"
>>>
>>> Ranges also support arbitrary functions, the doc page shows a Fibonacci number generator
>>> https://docs.raku.org/language/operators#index-entry-sequence_operator
>>> "This allows you to write
>>>
>>> say 1, 1, * + * ...^ *>= 100;
>>> # OUTPUT: «(1 1 2 3 5 8 13 21 34 55 89)␤»
>>>
>>> to generate all Fibonacci numbers up to but excluding 100."
>>>
>>>
>>>
>>>
>>> -y
>>>
>>>
>>> On Tue, Aug 24, 2021 at 6:36 PM William Michels via perl6-users <perl6-users@perl.org> wrote:
>>>
>>> Hi Marc,
>>>
>>> My understanding is that ranges are pretty cheap to construct, and in any case, the range @x[0..*-1] is just the index of all elements in @x. The .grep() approach may be most useful if you have a function (e.g. %, %%, and .is-prime shown below):
>>>
>>> > (0...9)
>>> (0 1 2 3 4 5 6 7 8 9)
>>> > (0...9)[0..*-1]
>>> (0 1 2 3 4 5 6 7 8 9)
>>> > (0...9)[(0..*-1).grep: * ]
>>> (0 1 2 3 4 5 6 7 8 9)
>>> > (0...9)[(0..*-1).grep: * %% 2 ]
>>> (0 2 4 6 8)
>>> > (0...9)[(0..*-1).grep: * % 2 ]
>>> (1 3 5 7 9)
>>> > (0...9)[(0..*-1).grep: *.is-prime ]
>>> (2 3 5 7)
>>> >
>>>
>>> You can find a related example in the docs ( https://docs.raku.org/routine/grep#class_HyperSeq). Anyway, I'm sure each approach has its fans,
>>>
>>> Best, Bill.
>>>
>>> On Tue, Aug 24, 2021 at 3:59 AM Marc Chantreux <eiro@phear.org> wrote:
>>>
>>> hello everyone,
>>>
>>> I made a mistake while replying to all of us so anwsers never reached
>>> your boxes. I'll summerize in one answer:
>>>
>>> Bill:
>>>
>>> > Is it just even/odd elements that you want to separate out? If so, maybe
>>> > .grep() is your friend here
>>>
>>> I don't think it is: 0, 2 ... * seems to be
>>>
>>> * closer to what i have in mind when i think about the problem
>>>   (so i invoke readability there)
>>> * probably more efficient than (0..*).grep(* % 2) that
>>>   * generate twice the number of required elements
>>>   * need to filter the result
>>>
>>> Also, trying to play with this version:
>>>
>>> my ($a,$b) =
>>>     .[0,2...*],
>>>     .[1,3...*]
>>>     with <AaBbCc>.comb;
>>>
>>> just don't work because the lists are squashed into scalar context
>>> in the process.
>>>
>>> So Brian and Fernando made my day with := and the unexpected power of
>>> the [] operator.
>>>
>>>     my (@a,@b) := <AaBbCc>.comb[ [0,2...*], [1,3...*] ];
>>>
>>> I really like how declarative it is. Also the use of := now seems
>>> obvious to me.
>>>
>>> Sigils still remains something strange to me desprite all your examples
>>> but i'll take some time. thanks everyone.
>>>
>>> marc
>>>
>>> CAUTION - EXTERNAL EMAIL: This email originated outside the Judiciary. Exercise caution when opening attachments or clicking on links.
>>>

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About