Peter
Peter Campbell Smith

Lot of ands and
a strange grid

Weekly challenge 163 — 2 May 2022

Week 163 - 2 May 2022

Task 2

Task — Summations

You are given a list of positive numbers, @n. Write a script to find out the summations as described below.

Examples


Example 1
Input: @n = (1, 2, 3, 4, 5)
Output: 42
    1 2 3  4  5
      2 5  9 14
        5 14 28
          14 42
             42
The nth row starts with the second element of the (n-1)th 
row. The following element is sum of all elements except 
first element of previous row. You stop once you have just
one element in the row.

Example 2
Input: @n = (1, 3, 5, 7, 9)
Output: 70
    1 3  5  7  9
      3  8 15 24
         8 23 47
           23 70
              70

Analysis

We are given a list of positive numbers and asked to generate a triangular array according to certain rules.

From the examples we can see that the first row of the output is just the input.

The nth row then has n - 1 blank columns, and subsequent columns contain the sum of the cell to the left and the cell above.

There is, as usual, the issue of producing pretty output, and I chose to output all the cells one character wider than the final cell, which is always going to be the largest number.

Try it 

Try running the script with any input:



example: 2, 4, 6, 8, 10

Script


#!/usr/bin/perl

# Peter Campbell Smith - 2022-05-03
# PWC 163 task 2

use v5.28;
use strict;
use warnings;
use utf8;

my (@tests, $test, @n, $rows, $row, $col, @grid, $width);

@tests = ([1, 2, 3, 4, 5], [1, 3, 5, 7, 9], [12, 32, 43, 72, 34, 99, 6, 50]);

# loop over tests
for $test (@tests) {
    @n = @$test;
    $rows = scalar @n;
    
    # create a grid of the output
    for $row (0 .. $rows - 1) {
        for $col (0 .. $rows - 1) {
            
            # the first row is just the input
            if ($row == 0) {
                $grid[0][$col] = $n[$col];
            
            # any cell where $col < $row is blank - so make it 0 for now
            } elsif ($col < $row) {
                $grid[$row][$col] = 0;
                
            # all the other cells are the sum of the cell to the left and the cell above
            } else {
                $grid[$row][$col] = $grid[$row - 1][$col] + $grid[$row][$col - 1];
            }
        }
    }
    
    # for a nice output the width of each column is the width of the final cell + 1
    $width = length($grid[$rows - 1][$rows - 1]) + 1;
    
    # output the result - padded to $width, or if zero, just $width spaces
    say '';
    for $row (0 .. $rows - 1) {
        for $col (0 .. $rows - 1) {
            print $grid[$row][$col] ? sprintf("\%${width}d", $grid[$row][$col]) : (' ' x $width);
        }
        say '';
    }   
}

Output


  1  2  3  4  5
     2  5  9 14
        5 14 28
          14 42
             42

  1  3  5  7  9
     3  8 15 24
        8 23 47
          23 70
             70

    12    32    43    72    34    99     6    50
          32    75   147   181   280   286   336
                75   222   403   683   969  1305
                     222   625  1308  2277  3582
                           625  1933  4210  7792
                                1933  6143 13935
                                      6143 20078
                                           20078