Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Grep Pattern

by GotToBTru (Prior)
on Dec 12, 2018 at 14:29 UTC ( #1227147=perlquestion: print w/replies, xml ) Need Help??

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

I want to apply a F T T F repeating pattern as a filter to an array or list. Here is what I came up with:

$i = 0; @result = grep { $i = 0 unless ($i<4); $i++%3 ? 1 : 0; } 0..12

@result = 1,2,5,6,9,10

It works but looks clunky. Any more elegant options?

But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)

Replies are listed 'Best First'.
Re: Grep Pattern
by hdb (Monsignor) on Dec 12, 2018 at 14:59 UTC

    You could pre-program your pattern, which imho is elegant and transparent and easily adaptable to more complex situations.

    @pat = ( 0, 1, 1, 0 ); $i = 0; @result = grep { $pat[ $i++ % 4 ] } 0..12;

    I guess you could also replace "4" with "@pat" to make it even more general.

      That's the approach I would recommend as well. But you kinda messed up on the implementation.
      my @pat = ( 0, 1, 1, 0 ); my @result = grep { $pat[ $_ % @pat ] } 0..12;
        > But you kinda messed up on the implementation.

        Not really, you are filtering the sample input, hdb is filtering any input by a "repeating pattern".

        update
        DB<10> @pat = ( 0, 1, 1, 0 ); DB<11> x $i=0;grep { $pat[ $i++ % 4 ] } a..l; 0 'b' 1 'c' 2 'f' 3 'g' 4 'j' 5 'k' DB<12>

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        that's elegant...

        $ ./1.grep_pattern.pl result is 1 2 5 6 9 10 $ cat 1.grep_pattern.pl #!/usr/bin/perl -w use 5.011; my @pat = ( 0, 1, 1, 0 ); my @result = grep { $pat[ $_ % @pat ] } 0..12; say "result is @result"; __END__ $
Re: Grep Pattern
by Eily (Monsignor) on Dec 12, 2018 at 14:39 UTC

    Having a TTFFTTFF... pattern is quite easy:

    DB<11> $i = 0; say for grep { $i++ % 4 < 2 } 0..12 0 1 4 5 8 9 12
    And starting at the fourth value in the pattern just means your start at the fourth value of $i:
    DB<12> $i = 3; say for grep { $i++ % 4 < 2 } 0..12 1 2 5 6 9 10

Re: Grep Pattern
by tybalt89 (Prior) on Dec 12, 2018 at 14:52 UTC
    #!/usr/bin/perl -l # https://perlmonks.org/?node_id=1227147 use strict; use warnings; my $pattern = '011'; my @result = grep $pattern =~ /./g && $&, 0..12; local $, = ','; print @result;
      What if the last element in the pattern is T, not F?

      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        Just invert the pattern and the test :)

        #!/usr/bin/perl -l # https://perlmonks.org/?node_id=1227147 use strict; use warnings; my $pattern = '011'; my @result = grep !($pattern =~ /./g && $&), 0..12; local $, = ','; print @result;

        Outputs:

        0,3,4,7,8,11,12
        Here I reset 'pos' when match approaches the end of the pattern, allowing second regex always match:
        #!/usr/bin/perl # https://perlmonks.org/?node_id=1227147 use warnings; use strict; my $pattern = 'FTTF'; my @result = grep { $pattern =~ /(?!$)/g; $pattern =~ /./g; $& eq 'T' } 0 .. 12; print "@result\n";
      Similar idea:
      #!/usr/bin/perl # https://perlmonks.org/?node_id=1227147 use warnings; use strict; my $pattern = 'FTTF'; my $repeated_pattern = $pattern x ( 1 + ( map $_, 0 .. 12 ) / length $ +pattern ); my @result = grep { $repeated_pattern =~ /./g; $& eq 'T' } 0 .. 12; print $repeated_pattern, "\n"; print "@result\n";
Re: Grep Pattern
by rsFalse (Hermit) on Dec 15, 2018 at 20:06 UTC
    Another one, with rotating:
    #!/usr/bin/perl # https://perlmonks.org/?node_id=1227147 use warnings; use strict; my $short_pattern = 'FTTF'; my @result = grep { $short_pattern = ( chop $short_pattern ) . $short_patt +ern; $short_pattern ge 'T' } 0 .. 12; print "@result\n";
    P.S. note a wrong rotation direction. So, the pattern should be reversed before, if it's not a palindrome.
Re: Grep Pattern
by LanX (Cardinal) on Dec 20, 2018 at 14:34 UTC
    slightly cheating ;-)

    DB<33> x @a=(0,1,1); grep { (each @a)[1] } A..L 0 'B' 1 'C' 2 'F' 3 'G' 4 'J' 5 'K'

    here the general case w/o cheating:

    (like when the filter cycle ends with a 1 you'd need)

    DB<34> x @a=(0,0,1,1); grep { (each @a)[1] // (each @a)[1] } A..L 0 'C' 1 'D' 2 'G' 3 'H' 4 'K' 5 'L'

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (8)
As of 2021-04-20 11:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?