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

I have an array with list of elements and I need to print maximum count of element which is repeated consecutively. I have written a script for the same, but meanwhile looking for any alternative solution/logic exists for the same.
use strict; use warnings; use Data::Dumper; my @a = ( 2,2,2,3,3,4,4 ); my (%hash, %count); my $prev; foreach ( 0..$#a ) { my $cur = $a[$_]; warn "cur:$cur\n"; if ( ($prev && $cur != $prev || $_ == $#a) ) { my ($prev_key) = keys %count; if ( !$prev_key ||( $count{$prev_key} ) <= $hash{$prev} ) { delete $count{$prev_key} if $prev_key; $count{$prev} = $hash{$prev}; } } $hash{$cur}++; $prev = $cur; } warn Dumper \%count;
Output:
$VAR1 = { '2' => 3 };
The answer should be '3'. Since element '2' has occured consecutively '3' times in the array.

Replies are listed 'Best First'.
Re: Print max count of repeated consecutive numbers in an array
by Corion (Patriarch) on Oct 06, 2021 at 12:47 UTC

    As the elements in your input array are counted consecutively, you can avoid the use of a hash and only need the count of the element and the value of the counted element. Maybe this is what your teacher mentions as feedback.

    Instead of using the hash, you can use simply the $prev_key variable and maybe introduce a variable $repeat_count instead of the count stored in %count.

Re: Print max count of repeated consecutive numbers in an array
by tybalt89 (Monsignor) on Oct 06, 2021 at 17:37 UTC

    At the request of LanX

    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11137256 use warnings; my @a = ( 2,2,2,3,3,4,4 ); my @best; $best[split] = (split)[0] for "@a" =~ /\b((\d+)(?: \2\b)*)/g; print "highest count is $#best for the number $best[-1]\n";

    Outputs:

    highest count is 3 for the number 2
Re: Print max count of repeated consecutive numbers in an array
by kcott (Archbishop) on Oct 07, 2021 at 00:09 UTC

    G'day vkk05,

    "... looking for any alternative solution/logic ..."

    The code in &get_max_count below provides a far less involved solution.

    Testing your algorithm with a single, ideal datum is never a good idea. I've used Test::More to show a common way of testing multiple items. You can simply add more test data to @tests; nothing else in the code needs to be changed.

    #!/usr/bin/env perl use strict; use warnings; use constant UNDEF => "\0"; use Test::More; my @tests = ( [qw{2 2 2 3 3 4 4}], [qw{2 2 3 3 4 4 2 2 2}], [qw{2 2 2 3 3 4 4 2 2}], [qw{2 2 2 3 3 4 4 4 5 6 6}], [qw{2 2 6 6 6 3 3 4 4 4 5}], [qw{2 2 3 3 4 4}, ('') x 3], [('') x 3, qw{2 2 3 3 4 4}], [('') x 2, qw{2 2 3 3 4 4}, ('') x 3], [qw{2 2 3 3 4 4}, (undef) x 3], [(undef) x 3, qw{2 2 3 3 4 4}], [(undef) x 2, qw{2 2 3 3 4 4}, (undef) x 3], [(undef) x 2, ('') x 2, qw{2 2 3 3 4 4}, ('') x 2, (undef) x 3], ); plan tests => 0+@tests; ok(get_max_count($_) == 3) for @tests; sub get_max_count { my ($data) = @_; my ($inst, $key, %consec, $last); for (@$data) { $_ = UNDEF unless defined; $last = "$_:$_" unless 0+keys(%consec); if ($_ ne $last) { $key = join '-', $_, ++$inst; $last = $_; } ++$consec{$key}; } return (sort { $b <=> $a } values %consec)[0]; }

    Output:

    1..12 ok 1 ok 2 ok 3 ok 4 ok 5 ok 6 ok 7 ok 8 ok 9 ok 10 ok 11 ok 12

    — Ken

Re: Print max count of repeated consecutive numbers in an array
by tybalt89 (Monsignor) on Oct 06, 2021 at 15:05 UTC
    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11137256 use warnings; my @a = ( 2,2,2,3,3,4,4 ); my @best = (my $count = 1, my $prev = shift @a); for my $next ( @a ) { $prev == $next or $prev = $next, $count = 0; $best[ ++$count ] = $next; } print "highest count is $#best for the number $best[-1]\n";

    Outputs:

    highest count is 3 for the number 2
Re: Print max count of repeated consecutive numbers in an array
by jo37 (Curate) on Oct 06, 2021 at 17:28 UTC

    If you'd like to use a sledgehammer to crack a nut:

    #!/usr/bin/perl use v5.16; use strict; use warnings; use PDL; my $list = long(2,2,2,3,3,4,4); my $rle = long(rle $list); my $ind = maximum_ind $rle->slice('X,(0)'); say $rle->slice("($ind)");

    Greetings,
    -jo

    $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$