in reply to Re: Can you write a faster code to perform this task?
in thread Can you write a faster code to perform this task?

tr counts single letters while the OP wants to count sequences of identical letters.

Cheers Rolf

(addicted to the Perl Programming Language and ☆☆☆☆ :)

  • Comment on Re^2: Can you write a faster code to perform this task?

Replies are listed 'Best First'.
Re^3: Can you write a faster code to perform this task?
by trizen (Hermit) on Sep 29, 2014 at 11:50 UTC
    What about something like this?
    use 5.014; say 'iiiiiiiiMMMMMMMMMMMooooooooooooMMMMMMMMMMiiiiiMMMMMMMMoooo' =~ tr/M/~/sr=~tr/~//; # => prints: 3
    Update: just to be sure, it would be safer to replace 'M' with something much exotic, like '\0', which should be OK, assuming that you're reading text files. (tr/M/\0/sr =~ tr/\0//)

      I tried it with replacing 'M' with 'M' and it worked. No need to worry about exotic characters.

      use 5.014; say 'iiiiiiiiMMMMMMMMMMMooooooooooooMMMMMMMMMMiiiiiMMMMMMMMoooo' =~ tr/M/M/sr=~tr/M//; # => prints: 3

        No need for a new perl and the /r option either. This works fine:

        #! perl -slw use strict; use Time::HiRes qw[ time ]; my $start = time; my $count=0; while( <DATA> ) { # $count += ()= m{M+}g; tr/M/M/s; $count += tr/M/M/; } print $count."\n"; printf "Took %9f secs\n", time() - $start;

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
      Well TIMTOWTDI with two chained tr is not necessarily fast. :)

      But who knows, try to benchmark... :)

      Cheers Rolf

      (addicted to the Perl Programming Language and ☆☆☆☆ :)

        tr is MUCH faster than s though. I tried to work this out but didn’t hit on trizen’s cleverness. So…

        # (v5.18.2) built for darwin-2level 'tr' => sub { $str =~ tr/M/~/sr=~tr/~//; }, -- count 3 regex 3 regex2 3 split 3 tr 3 Rate regex2 split regex count tr regex2 169354/s -- -62% -65% -75% -94% split 446500/s 164% -- -7% -34% -85% regex 481882/s 185% 8% -- -29% -84% count 674634/s 298% 51% 40% -- -78% tr 3044813/s 1698% 582% 532% 351% --

        Update: as trizen noted in his code, the /r flag to tr came in at 5.14. It won’t work on older Perls (update: <- stupid apostrophe begone).

Re^3: Can you write a faster code to perform this task?
by Laurent_R (Canon) on Sep 29, 2014 at 17:25 UTC
    True, Rolf, I mis-read the OP's requirement. I thought he wanted the number of "M". But, OTOH, trizen has found a way to use tr/// which seems to be very fast.