TL;DR

Here we are with TASK #1 from the Perl Weekly Challenge #116. Enjoy!

The challenge

You are given a number $N >= 10. Write a script to split the given number such that the difference between two consecutive numbers is always 1 and it shouldnâ€™t have leading 0. Print the given number if it impossible to split the number. Example Input:$N = 1234
Output: 1,2,3,4

Input: $N = 91011 Output: 9,10,11 Input:$N = 10203
Output: 10203 as it is impossible to split satisfying the conditions.


The questions

I have to admit that I didnâ€™t get the challenge just by reading it. In my brain, split a number means dividing it into a sum; this time, though, weâ€™re playing with the ambiguity of considering a number by its string representation in base 10. As usual, anyway, the examples make an excellent job of clarifying things.

Itâ€™s also interesting to note that the output value for when there is no way to split the input number is actually a valid number splitting - one with one single element only. This makes the restriction about $N >= 10 a bit arbitrary but whatever, not counting e.g. that -101 would be a perfect fit. Whatever. The solution We just do a plain search here, starting with the first character, then two, etc. up to one half of the string representation. Anything beyond would not be a good division and can be skipped. One of the examples is a blessing: 91011. It makes it perfectly clear that the number of characters to be consumed is variable - in this case, it starts from 1 and then lands on 2. Hence, thereâ€™s no evident way to rule out stuff - although something might be coded, admittedly. Hereâ€™s my solution in Perl: #!/usr/bin/env perl use 5.024; use warnings; use experimental qw< postderef signatures >; no warnings qw< experimental::postderef experimental::signatures >; sub number_sequence ($N) {
my $length = length$N;
SIZE:
for my $l (1 ..$length / 2) {
my @retval = my $x = substr$N, 0, $l; my$start = $l; ++$x;
while ((my $available =$length - $start) > 0) { my$xlen = length $x; next SIZE if$xlen > $available || substr($N, $start,$xlen) ne $x; push @retval,$x;
$start +=$xlen;
++$x; } return @retval; } return$N;
}

my @inputs = @ARGV ? @ARGV : qw< 1234 91011 10203 >;
say join ',', number_sequence($_) for @inputs;  Hereâ€™s the corresponding solution in Raku: #!/usr/bin/env raku use v6; sub number-sequence (Int$N where * >= 10) {
my $Nlength =$N.chars;
SIZE:
for 1 .. ($Nlength / 2) ->$l {
my @retval = my $x =$N.substr(0, $l); my$start = $l; ++$x;
while (my $available =$Nlength - $start) > 0 { my$xlen = $x.chars; next SIZE if$xlen > $available ||$N.substr($start,$xlen) ne $x; @retval.push($x);
$start +=$xlen;
++$x; } return @retval; } return$N;
}

sub MAIN (*@inputs) {
@inputs = < 1234 91011 10203 > unless @inputs.elems;
number-sequence(\$_).join(',').put for @inputs;
}


Stay safe!

Comments? Octodon, , GitHub, Reddit, or drop me a line!