Robbie Hatley's Solutions To The Weekly Challenge #267

For those not familiar with "The Weekly Challenge", it is a weekly programming puzzle with two parts, cycling every Sunday. You can find it here:

The Weekly Challenge

This week (2024-04-28 through 2024-05-04) is weekly challenge #267. Its tasks are as follows:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Task 267-1: Product Sign
Submitted by: Mohammad Sajid Anwar

You are given an array of @ints. Write a script to find the sign of the 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 1 input:
[-1, -2, -3, -4, 3, 2, 1]
Expected output: 1

Example 2 input:
[1, 2, 0, -2, -1]
Expected output: 0

Example 3 input:
[-1, -1, 1, -1, 2]
Expected output: -1

The sign of the product is the product of the signs, and sign(x) is given by "0 if x is 0, else x/abs(x)". So these subs should work:

   use v5.36;
   use List::Util 'product';
   sub sign($x) {0==$x and return 0 or return $x/abs($x)}
   sub product_sign (@a) {return product map {sign($_)} @a;}

Robbie Hatley's Perl Solution to The Weekly Challenge 267-1

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Task 267-2: Line Counts
Submitted by: Mohammad Sajid Anwar

You are given a string, $str, and a 26-items array @widths containing the width (in pixels) of each character from a to z. Write a script to find out the number of lines and the width of the last line needed to display the given string, assuming you can only fit 100 width units on a line.

Example 1 inputs:
   $str = "abcdefghijklmnopqrstuvwxyz"
   @widths = (10,10,10,10,10,10,10,10,10,10,
              10,10,10,10,10,10,10,10,10,10,
              10,10,10,10,10,10)
Expected output: (3, 60)
Line 1: abcdefghij (100 pixels)
Line 2: klmnopqrst (100 pixels)
Line 3: uvwxyz (60 pixels)

Example 2 inputs:
   $str = "bbbcccdddaaa"
   @widths = ( 4,10,10,10,10,10,10,10,10,10,
              10,10,10,10,10,10,10,10,10,10,
              10,10,10,10,10,10)
Expected output: (2, 4)
Line 1: bbbcccdddaa (98 pixels)
Line 2: a (4 pixels)

I think I'll first store the 26 widths in a hash keyed by letter, then fill up lines in an array until I'm out of characters, then return the scalar of that array (line count) and the length of the last element (last-line length). Something like this:

   sub lines ($str, @widths) {
      return (0,0) if !is_az_string($str);
      return (0,0) if !are_26_posints(@widths);
      my @letters = 'a'..'z';
      my %w = mesh @letters, @widths;
      my @lines ;
      my ($line, $width, $next, $wext);
      while ($str) {
         ($line, $width, $next, $wext) = ('',0,'',0);
         while ($str && $width + ($wext = $w{$next = substr($str, 0, 1)}) <= 100) {
            $line  .= $next;
            $width += $wext;
            substr($str, 0, 1, '');
         }
         push @lines, $line;
      }
      return (scalar(@lines), $width, @lines);
   }

Robbie Hatley's Perl Solution to The Weekly Challenge 267-2

That's it for challenge 267; see you on challenge 268!

Comments

Popular posts from this blog

Robbie Hatley's Solutions To The Weekly Challenge #221

Robbie Hatley's Solutions To The Weekly Challenge #239

Robbie Hatley's Solutions To The Weekly Challenge #262