Weekly Challenge 373
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. Unless otherwise stated, Copilot (and other AI tools) have NOT been used to generate the solution. It's a great way for us all to practice some coding.
Task 1: Equal List
Task
You are given two arrays of strings.
Write a script to return true if the two given array represent the same strings otherwise false.
My solution
For input from the command line, I take a string with items concatenated by commas to generate the two lists. This seems to the easiest way to handle this, allowing for empty items as per the fourth example.
def main():
result = equal_list(sys.argv[1].split(","), sys.argv[2].split(","))
print("true" if result else "false")
This function is a one liner. I join the items in each list and then compare them to see if they are the same.
def equal_list(arr1: list[str], arr2: list[str]) -> bool:
return ''.join(arr1) == ''.join(arr2)
The Perl solution has the same functionality.
sub main ( $str1, $str2 ) {
my @arr1 = split /,/, $str1;
my @arr2 = split /,/, $str2;
say join( "", @arr1 ) eq join( "", @arr2 ) ? "true" : "false";
}
Examples
$ ./ch-1.py "a,bc" "ab,c"
false
$ ./ch-1.py "a,bc" "ab,c"
true
$ ./ch-1.py "a,b,c" "a,bc"
true
$ ./ch-1.py "a,bc" "a,c,b"
false
$ ./ch-1.py "ab,c," ",a,bc"
true
$ ./ch-1.py "p,e,r,l" "perl"
true
Task 2: List Division
Task
You are given a list and a non-negative integer.
Write a script to divide the given list into given non-negative integer equal parts. Return -1 if the integer is more than the size of the list.
My solution
For this task, I use the divmod function to calculate the number of items from the list each part needs, and the number of parts that require an extra item. These are stored as the variables item_length and extra_first.
I also have a variable called pos to store the position of the first letter. I have a loop i that runs n times. If i is less than extra_first, I take item_length + 1 items, otherwise item_length times, adding to pos as I go.
def list_division(input_list: list[int], n: int) -> list[list[int]] | None:
result = []
pos = 0
if len(input_list) < n:
return None
item_length, extra_first = divmod(len(input_list), n)
for i in range(n):
this_length = item_length + 1 if i < extra_first else item_length
result.append(input_list[pos:pos+this_length])
pos += this_length
return result
The Perl solution is similar. It doesn't have the pos variable, as it uses the splice function to remove the necessary number of items from the array. This function returns the items removed.
sub main (@list) {
# The last value is the 'n' value
my $n = pop(@list);
my $length = scalar(@list);
my @result = ();
if ( $length < $n ) {
say -1;
return;
}
my $item_length = int( $length / $n );
my $extra_first = $length % $n;
foreach my $i ( 1 .. $n ) {
my $this_length = $i <= $extra_first ? $item_length + 1 : $item_length;
push @result, "(" . join( ",", splice( @list, 0, $this_length ) ) . ")";
}
say "(" . join( ", ", @result ) . ")";
}
Examples
$ ./ch-2.py 1 2 3 4 5 2
((1,2,3), (4,5))
$ ./ch-2.py 1 2 3 4 5 6 3
((1,2), (3,4), (5,6))
$ ./ch-2.py 1 2 3 2
((1,2), (3))
$ ./ch-2.py 1 2 3 4 5 6 7 8 9 10 5
((1,2), (3,4), (5,6), (7,8), (9,10))
$ ./ch-2.py 1 2 3 4
-1
$ ./ch-2.py 72 57 89 55 36 84 10 95 99 35 7
((72,57), (89,55), (36,84), (10), (95), (99), (35))
Top comments (0)