Peter’s blog ✴ Week 140 ✴ 22 November 2021

THE WEEKLY CHALLENGE
Add and multiply

The Perl Camel

Task 2

Multiplication table

You are given 3 positive integers, $i, $j and $k. Write a script to print the $kth element in the sorted multiplication table of $i and $j.

Examples


Example 1
Input: $i = 2; $j = 3; $k = 4
Output: 3
Since the multiplication of 2 x 3 is as below:
    1 2 3
    2 4 6
The sorted multiplication table:
    1 2 2 3 4 6
Now the 4th element in the table is "3".

Example 2
Input: $i = 3; $j = 3; $k = 6
Output: 4
Since the multiplication of 3 x 3 is as below:
    1 2 3
    2 4 6
    3 6 9
The sorted multiplication table:
    1 2 2 3 3 4 6 6 9
Now the 6th element in the table is "4".

Analysis

There seem to be 2 options here:

  1. Do it as per the examples, ie create the table, sort it and then look for the $kth element.
  2. Device an ingenious way to calculate the value of the $kth element without calculating the table.

I completely failed with method 2, and my solution therefore uses method 1.

It is true that the calculation time for method 1 grows fast as $i and $j increase, so if anyone has a real need for this I suggest they look at other submitted responses for someone who has managed a solution using method 2.

I am sorry that the 'Try it' feature is currently working very slowly or not at all owing to some issue with my web hosting provider.

Try it 

Try running the script with any input:



example: 3, 4, 5

Script


#!/usr/bin/perl

# Peter Campbell Smith - 2021-11-22
# PWC 140 task 2

use v5.20;
use warnings;
use strict;

my (@tests, $test, $i, $j, $k, @results, $i0, $j0);

# i, j, k sets to be tested
@tests = ([2, 3, 4], [3, 3, 6], [20, 30, 599], [1000, 999, 314159], [5, 6, 30]);

# loop over tests
for $test (@tests) {
    
    # we want the $nth product in $results[$n] so dummy out $results[0]
    @results = (0);
    ($i, $j, $k) = @$test;
    say qq[\nInput:  \$i = $i, \$j = $j, \$k = $k];
    if ($k > $i * $j or $k <= 0) {
        say qq[\$k must be in the range 1 .. ] . ($i * $j);
        next;
    }
    
    # make table
    for $i0 (1 .. $i) {
        for $j0 (1 .. $j) {
            push (@results, $i0 * $j0);
        }
    }
    
    # sort results and print desired one
    @results = sort {$a <=> $b} @results;
    
    say qq[Output: $results[$k]\n];
}

17 lines of code

Output from script


Input:  $i = 2, $j = 3, $k = 4
Output: 3


Input:  $i = 3, $j = 3, $k = 6
Output: 4


Input:  $i = 20, $j = 30, $k = 599
Output: 580


Input:  $i = 1000, $j = 999, $k = 314159
Output: 93532


Input:  $i = 5, $j = 6, $k = 30
Output: 30

 

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