The weekly challenge 238 - Task 2: Persistence Sort

 1 #!/usr/bin/perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-238/#TASK2
 3 #
 4 # Task 2: Persistence Sort
 5 # ========================
 6 #
 7 # You are given an array of positive integers.
 8 #
 9 # Write a script to sort the given array in increasing order with respect to
10 # the count of steps required to obtain a single-digit number by multiplying
11 # its digits recursively for each array element. If any two numbers have the
12 # same count of steps, then print the smaller number first.
13 #
14 ## Example 1
15 ##
16 ## Input: @int = (15, 99, 1, 34)
17 ## Output: (1, 15, 34, 99)
18 ##
19 ## 15 => 1 x 5 => 5 (1 step)
20 ## 99 => 9 x 9 => 81 => 8 x 1 => 8 (2 steps)
21 ## 1  => 0 step
22 ## 34 => 3 x 4 => 12 => 1 x 2 => 2 (2 steps)
23 #
24 ## Example 2
25 ##
26 ## Input: @int = (50, 25, 33, 22)
27 ## Output: (22, 33, 50, 25)
28 ##
29 ## 50 => 5 x 0 => 0 (1 step)
30 ## 25 => 2 x 5 => 10 => 1 x 0 => 0 (2 steps)
31 ## 33 => 3 x 3 => 6 (1 step)
32 ## 22 => 2 x 2 => 4 (1 step)
33 #
34 ############################################################
35 ##
36 ## discussion
37 ##
38 ############################################################
39 #
40 # By creating a helper function that calculates the persistence,
41 # the actual function is basically calling the right sort function
42 use strict;
43 use warnings;
44 
45 persistence_sort(15, 99, 1, 34);
46 persistence_sort(50, 25, 33, 22);
47 
48 sub persistence_sort {
49    my @int = @_;
50    print "Input: (" . join(", ", @int) . ")\n";
51    my @result = sort { persistence($a) <=> persistence($b) || $a <=> $b } @int;
52    print "Output: (" . join(", ", @result) . ")\n";
53 }
54 
55 sub persistence {
56    my $number = shift;
57    my @digits = split //, $number;
58    return 0 unless @digits > 1;
59    my $prod = 1;
60    foreach my $d (@digits) {
61       $prod *= $d;
62    }
63    return 1 + persistence($prod);
64 }