Perl Weekly Challenge 283: Digit Count Value

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

Spoiler Alert: 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 2: Digit Count Value

You are given an array of positive integers, @ints.

Write a script to return true if for every index i in the range 0 <= i < size of array, the digit i occurs exactly the $ints[$i] times in the given array otherwise return false.

Example 1

Input: @ints = (1, 2, 1, 0)
Ouput: true

$ints[0] = 1, the digit 0 occurs exactly 1 time.
$ints[1] = 2, the digit 1 occurs exactly 2 times.
$ints[2] = 1, the digit 2 occurs exactly 1 time.
$ints[3] = 0, the digit 3 occurs 0 time.

Example 2

Input: @ints = (0, 3, 0)
Ouput: false

$ints[0] = 0, the digit 0 occurs 2 times rather than 0 time.
$ints[1] = 3, the digit 1 occurs 0 time rather than 3 times.
$ints[2] = 0, the digit 2 occurs exactly 0 time.

Digit Count Value in Raku

We first use a Bag to create the count histogram of frequencies. For some obscure reason, I wasn't able to use the bag directly (as I did for task 1 of this same challenge), and has to coerce the bag into a hash. Then, we check for each index in the array range that the input value matches the count. Actually, we return False if it doesn't match, and return True at the end of the loop if we reach there.

sub digit-count-value (@in) {
    my %count = @in.Bag;
    for 0..@in.end -> $i {
        return False if %count{$i}:exists and 
            @in[$i] != %count{$i};
    }
    return True;
}

my @tests = <1 2 1 0>, <0 3 0>; 
for @tests -> @test {
    printf "%-8s => ", "@test[]";
    say digit-count-value @test;
}

This program displays the following output:

$ raku ./digit-count-value.raku
1 2 1 0  => True
0 3 0    => False

Digit Count Value in Perl

This is a port to Perl of the above Raku program. Note that we use a hash (%count) to host the histogram of frequencies.

use strict;
use warnings;
use feature 'say';

sub digit_count_value {
    my @in = @_;
    my %count;
    $count{$_}++ for @in;
    for my $i (0..$#in) {
        return "False" if exists $count{$i} and 
            $in[$i] != $count{$i};
    }
    return "True";
}

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

This program displays the following output:

$ perl ./digit-count-value.pl
1 2 1 0  => True
0 3 0    => False

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 1, 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.