Peter’s blog ✴ Week 283 ✴ 19 August 2024

THE WEEKLY CHALLENGE
Occurrences

The Perl Camel

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 $ints[$i] times in the given array; otherwise return false.

Examples


Example 1
Input: @ints = (1, 2, 1, 0)
Output: 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)
Output: 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.

Analysis

I have provided a solution that checks @ints as stated. First it calculates the frequency $freq{$i} of $i in the array. Then for each element of @ints it performs the check stated in the challenge: $ints[$i] == $freq{$i} and the result is the logical and of that for all $i.

However, there are remarkably few arrays for which the result is true. I checked up to 7 members of the array and the only compliant ones I found are:

1, 2, 1, 0
2, 0, 2, 0
2, 1, 2, 0, 0
3, 2, 1, 1, 0, 0, 0

So an alternative solution would simply be to check if the array is any of these.

Perl Weekly’s review

from Perl Weekly issue 683

Try DIY tool to play with your sample data. Interface is very user friendly to keep you engage. Thanks for your contributions.

Try it 

Try running the script with any input:



example: 3, 2, 1, 1, 0, 0, 0

Script


#!/usr/bin/perl

# Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge

use v5.26;    # The Weekly Challenge - 2024-08-19
use utf8;     # Week 283 - task 2 - Digit count value
use warnings; # Peter Campbell Smith
binmode STDOUT, ':utf8';

digit_count_value(1, 2, 1, 0);
digit_count_value(0, 3, 0);
digit_count_value(1, 2, 3, 2, 1, 0);

sub digit_count_value {
    
    my (@ints, %freq, $i, $result);
    
    # calculate frequency of each occurring element
    @ints = @_;
    $freq{$_} ++ for @ints;
    
    # test the challenge assertion
    $result = 'true';
    for $i (0 .. @ints - 1) {
        
        # zero is allowed
        $freq{$i} = 0 unless defined $freq{$i};
        
        # quit unless assertion is true
        if ($ints[$i] != $freq{$i}) {
            $result = qq[false ∵ \$ints[$i] = $ints[$i] and $i occurs $freq{$i} times];
            last;
        }
    }
    
    say qq[\nInput:  \@ints = (] . join(', ', @ints) . ')';
    say qq[Output: $result];
}

12 lines of code

Output from script


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

Input:  @ints = (0, 3, 0)
Output: false ∵ $ints[0] = 0 and 0 occurs 2 times

Input:  @ints = (1, 2, 3, 2, 1, 0)
Output: false ∵ $ints[2] = 3 and 2 occurs 2 times

 

Any content of this website which has been created by Peter Campbell Smith is in the public domain