Perl Weekly Challenge 284: Lucky Integer

These are some answers to the Week 284, Task 1, of the Perl Weekly Challenge organized by Mohammad S. Anwar.

Spoiler Alert: This weekly challenge deadline is due in a few days from now (on September 1, 2024, at 23:59). This blog post provides some solutions to this challenge. Please don’t read on if you intend to complete the challenge on your own.

Task 1: Lucky Integer

You are given an array of integers, @ints.

Write a script to find the lucky integer if found otherwise return -1. If there are more than one then return the largest.

A lucky integer is an integer that has a frequency in the array equal to its value.

Example 1

Input: @ints = (2, 2, 3, 4)
Output: 2

Example 2

Input: @ints = (1, 2, 2, 3, 3, 3)
Output: 3

Example 3

Input: @ints = (1, 1, 1, 3)
Output: -1

We will assume that the input array contains only strictly positive integers, as in the examples provided. Negative numbers would not make sense in the context, as a negative frequency is impossible.

Lucky Integer in Raku

Once again, we use a Bag to create the $count histogram of frequencies. Then, we create an array of items whose count is equal to the key value. And we return -1 if none was found, and the max value otherwise.

sub lucky-integer (@in) {
    my $count = @in.Bag;
    my @lucky = grep { $_ == $count{$_} }, $count.keys;
    return -1 if @lucky.elems == 0;
    return @lucky.max;
}

my @tests = <2 2 3 4>, <1 2 2 3 3 3>, <1 1 1 3>;
for @tests -> @test {
    printf "%-12s => ", "@test[]";
    say lucky-integer @test;
}

This program displays the following output:

$ raku ./lucky-integer.raku
2 2 3 4      => 2
1 2 2 3 3 3  => 3
1 1 1 3      => -1

Lucky Integer in Perl

This is a port to Perl of the above Raku program. Note that we use a hash (%count) instead of a Bag to host the histogram of frequencies. We also need a loop to find maximum value in the @lucky array.

sub lucky_integer {
    my %count;
    $count{$_}++ for @_;
    my @lucky = grep { $_ == $count{$_} } keys %count;
    return -1 if $#lucky == 0;
    my $max = shift @lucky;
    for my $i (@lucky) {
        $max = $i if $i > $max;
    }
    return $max;
}

my @tests = ( [<2 2 3 4>], [<1 2 2 3 3 3>], [<1 1 1 3>] );
for my $test (@tests) {
    printf "%-12s => ", "@$test";
    say lucky_integer @$test;
}

This program displays the following output:

$ raku ./lucky-integer.raku
2 2 3 4      => 2
1 2 2 3 3 3  => 3
1 1 1 3      => -1

Wrapping up

The next week Perl Weekly Challenge will start soon. If you want to participate in this challenge, please check https://perlweeklychallenge.org/ and make sure you answer the challenge before 23:59 BST (British summer time) on September 9, 2024. And, please, also spread the word about the Perl Weekly Challenge if you can.

Leave a comment

About laurent_r

user-pic I am the author of the "Think Perl 6" book (O'Reilly, 2017) and I blog about the Perl 5 and Raku programming languages.