THE WEEKLY CHALLENGE - 238

https://theweeklychallenge.org/blog/perl-weekly-challenge-238/

Table of Contents

Task 1 - Running sum

Problem Statement

Given an array of integers, write a script to return the running sum of the given array. The running sum can be calculated as sum[i]=num[0]+num[1]+…+num[i]sum[i]=num[0]+num[1]+…+num[i].

Python Solution

Python offers a variety of ways to approach this problem. A basic loop-based solution was initially implemented. However, Python's standard library provides a more idiomatic way using itertools.accumulate.

from itertools import accumulate
from typing import List

def running_sum(nums: List[int]) -> List[int]:
    return list(accumulate(nums))

Perl and Raku Solutions

Perl and Raku also offer simple ways to solve this problem. Here's the Perl version:

sub running_sum {
    my @nums = @_;
    my $sum = 0;
    my @result;

    for my $num (@nums) {
        $sum += $num;
        push @result, $sum;
    }

    return \@result;
}

And the Raku version:

sub running-sum(@nums) {
    my @result;
    my $sum = 0;

    for @nums -> $num {
        $sum += $num;
        @result.push($sum);
    }

    return @result;
}

Both the Perl and Raku solutions use a similar approach: we initialize a sum variable and iteratively add each number in the array, appending the new sum to the result array.


Task 2 - Persistence Sort

Problem Statement

Given an array of positive integers, sort the array with respect to the number of steps required to reach a single-digit number by multiplying its digits recursively.

For example,

  • Input: [15, 99, 1, 34]
  • Output: [1, 15, 34, 99]

Python Solution

The Python solution involves defining a helper function steps_to_single_digit to calculate the steps needed for each number, and then sort the array based on those steps.

def persistence_sort(nums: List[int]) -> List[int]:
    def steps_to_single_digit(n: int) -> int:
        steps = 0
        while n >= 10:
            product = 1
            for digit in str(n):
                product *= int(digit)
            n = product
            steps += 1
        return steps

    return sorted(nums, key=lambda x: (steps_to_single_digit(x), x))

Perl Solution

The Perl solution follows the same logic:

sub persistence_steps {
    my $num = shift;
    my $count = 0;
    while ($num >= 10) {
        $count++;
        $num = reduce { $a * $b } split('', $num);
    }
    return $count;
}

# Function to sort array based on persistence steps
sub persistence_sort {
    my @arr = @_;
    return sort {
        my $steps_a = persistence_steps($a);
        my $steps_b = persistence_steps($b);
        $steps_a <=> $steps_b || $a <=> $b
    } @arr;
}

Raku Solution

In Raku, the code looks like this:

sub calc_steps(Int $num) {
    my $steps = 0;
    my $n = $num;

    while $n.chars > 1 {
        $n = [*] $n.comb.map(*.Int);
        $steps++;
    }

    return $steps;
}

# Function to perform persistence sort
sub persistence-sort(@arr) {
    return @arr.sort({ calc_steps($_) })».Int;
}

And there you have it! Solutions for both tasks in Python, Perl, and Raku. Each language has its own idiomatic way of solving the problem, and it's interesting to see how they differ. Thank you for reading!