Peter
Peter Campbell Smith

Pandigitals and term counts

Weekly challenge 134 — 11 October 2021

Week 134: 11 Oct 2021

Task 2

Task — Distinct terms count

You are given 2 positive numbers, $m and $n. Write a script to generate multiplcation table and display count of distinct terms.

Examples


Example 1
Input: $m = 3, $n = 3
Output:
      x | 1 2 3
      --+------
      1 | 1 2 3
      2 | 2 4 6
      3 | 3 6 9
Distinct Terms: 1, 2, 3, 4, 6, 9
Count: 6

Example 2
Input: $m = 3, $n = 5
Output:
      x | 1  2  3  4  5
      --+--------------
      1 | 1  2  3  4  5
      2 | 2  4  6  8 10
      3 | 3  6  9 12 15
Distinct Terms: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15
Count: 11

Analysis

The hardest part of this challenge is formatting the output.

With that conquered, 2 nested loops generate the multiplication table, and each entry is saved as $terms[$j * $k], thus ensuring that duplicated entries are merged.

Try it 

Try running the script with any input:



example: 5



example: 6

Script


#!/usr/bin/perl

# Peter Campbell Smith - 2021-10-13
# PWC 134 task 2

use v5.20;
use warnings;
use strict;

my ($m, $n, $col_width, $j, $k, $term, @terms, $line, $count, @tests, $test);

# get params
@tests = ([2, 3], [5, 6], [15, 12]);

# loop over tests
for $test (@tests) {
    ($m, $n) = @$test;
    @terms = ();
    $line = '';
    print qq[\nInput: \$m = $m, \$n = $n\nOutput:\n\n];

    # calculate column width = width of largest term + 1
    $col_width = int(log($m * $n)/log(10)) + 1;

    # print top row and underline
    print sprintf(" %${col_width}s", 'x') . ' |';
    for $j (1 .. $n) {
        print sprintf(" %${col_width}d", $j);
    }
    print qq[\n];
    print '-' x ($col_width + 2) . '+' . '-' x (($col_width + 1) * $n) . "\n";

    # print other rows
    for $j (1 .. $m) {
        print sprintf(" %${col_width}d", $j) . ' |';
        for $k (1 .. $n) {
            $term = $j * $k;
            print sprintf(" %${col_width}d", $term);
            $terms[$term] = 1;
        }
        print qq[\n];
    }

    # print unique terms nicely
    for $j (0 .. @terms - 1) {
        $line .= ($j + 0) . ', ' if $terms[$j];
    }
    say '';
    multiline(qq[Distinct terms: ], substr($line, 0, -2), 57, ',', 3);
}

sub multiline {
    
    my ($prefix, $text, $width, $separator, $margin, $this_line, $intro);
    
    ($prefix, $text, $width, $separator, $margin) = @_;
    
    # split long string over lines max width $width
    $intro = $prefix;
    while (length($intro) + length($text) > $width) {
        $this_line = substr($text, 0, $width - length($intro));
        $this_line =~ m|(.*$separator)|;
        say $intro . $1;        
        $text = substr($text, length($1), 99999);
        $intro = ' ' x $margin;
        $text =~ s|^\s*||;
    }
    say $intro . $text if $text !~ m|^\s*$|;
    return;
}

Output


Input: $m = 2, $n = 3
Output:

 x | 1 2 3
---+------
 1 | 1 2 3
 2 | 2 4 6

Distinct terms: 1, 2, 3, 4, 6

Input: $m = 5, $n = 6
Output:

  x |  1  2  3  4  5  6
----+------------------
  1 |  1  2  3  4  5  6
  2 |  2  4  6  8 10 12
  3 |  3  6  9 12 15 18
  4 |  4  8 12 16 20 24
  5 |  5 10 15 20 25 30

Distinct terms: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16,
   18, 20, 24, 25, 30

Input: $m = 15, $n = 12
Output:

   x |   1   2   3   4   5   6   7   8   9  10  11  12
-----+------------------------------------------------
   1 |   1   2   3   4   5   6   7   8   9  10  11  12
   2 |   2   4   6   8  10  12  14  16  18  20  22  24
   3 |   3   6   9  12  15  18  21  24  27  30  33  36
   4 |   4   8  12  16  20  24  28  32  36  40  44  48
   5 |   5  10  15  20  25  30  35  40  45  50  55  60
   6 |   6  12  18  24  30  36  42  48  54  60  66  72
   7 |   7  14  21  28  35  42  49  56  63  70  77  84
   8 |   8  16  24  32  40  48  56  64  72  80  88  96
   9 |   9  18  27  36  45  54  63  72  81  90  99 108
  10 |  10  20  30  40  50  60  70  80  90 100 110 120
  11 |  11  22  33  44  55  66  77  88  99 110 121 132
  12 |  12  24  36  48  60  72  84  96 108 120 132 144
  13 |  13  26  39  52  65  78  91 104 117 130 143 156
  14 |  14  28  42  56  70  84  98 112 126 140 154 168
  15 |  15  30  45  60  75  90 105 120 135 150 165 180

Distinct terms: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
   13, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28,
   30, 32, 33, 35, 36, 39, 40, 42, 44, 45, 48, 49, 50,
   52, 54, 55, 56, 60, 63, 64, 65, 66, 70, 72, 75, 77,
   78, 80, 81, 84, 88, 90, 91, 96, 98, 99, 100, 104, 105,
   108, 110, 112, 117, 120, 121, 126, 130, 132, 135, 140,
   143, 144, 150, 154, 156, 165, 168, 180

 

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