Product lines

Weekly challenge 267 — 29 April 2024

Week 267: 29 Apr 2024

Task 1

You are given an array of @ints. Write a script to find the sign of product of all integers in the given array. The sign is 1 if the product is positive, -1 if the product is negative and 0 if product is zero.

Example 1Input: @ints = (-1, -2, -3, -4, 3, 2, 1) Output: 1 The product -1 x -2 x -3 x -4 x 3 x 2 x 1 => 144 > 0Example 2Input: @ints = (1, 2, 0, -2, -1) Output: 0 The product 1 x 2 x 0 x -2 x -1 => 0Example 3Input: @ints = (-1, -1, 1, -1, 2) Output: -1 The product -1 x -1 x 1 x -1 x 2 => -2 < 0

There are a number of ways of performing this task. Let's start with the obvious one (method 1):

$product *= $_ for @ints; say qq[Output1: ] . ($product ? $product / abs($product) : 0);

So that's multiply the numbers together and if the product is zero, output that, or else divide the product by its absolute value and output that.

That works for the examples given, but:

- we could stop the multiplication if we find a zero, as no subsequent number will make the product non-zero,
- If
`@ints`

contains some big numbers we could quickly exceed Perl's largest integer - multiplication is moderately expensive, and we don't actually need the product.

So here's method 2.

Set `$result = 1`

, loop `for $int (@ints)`

and:

- if
`$int`

is positive, do nothing, - if
`$int`

is negative, reverse the sign of`$result`

, or - if
`$int`

is zero, set`$result = 0`

and quit the loop.

This resolves all three of the issues listed above.

#!/usr/bin/perl # Blog: http://ccgi.campbellsmiths.force9.co.uk/challenge use v5.26; # The Weekly Challenge - 2024-04-29 use utf8; # Week 267 - task 1 - Product sign use warnings; # Peter Campbell Smith binmode STDOUT, ':utf8'; product_sign(-1, -2, -3, -4, 3, 2, 1); product_sign(-1, -2, -3, 4, 3, 2, 1); product_sign(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -11); sub product_sign { my (@ints, $product, $int, $result); @ints = @_; say qq[\nInput: \@ints = (] . join(', ', @ints) . ')'; # method 1 - simple $product = 1; $product *= $_ for @ints; say qq[Output1: ] . ($product ? $product / abs($product) : 0); # method 2 - more efficient $result = 1; for $int (@ints) { next if ($int > 0); if ($int == 0) { $result = 0; last; } $result = -$result; } say qq[Output2: $result]; }

Input: @ints = (-1, -2, -3, -4, 3, 2, 1) Output1: 1 Output2: 1 Input: @ints = (-1, -2, -3, 4, 3, 2, 1) Output1: -1 Output2: -1 Input: @ints = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -11) Output1: 0 Output2: 0

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