AI News Hub Logo

AI News Hub

Weekly Challenge: Joining and splitting lists

DEV Community
Simon Green

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. Challenge, My solutions You are given two arrays of strings. Write a script to return true if the two given array represent the same strings otherwise false. 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"; } $ ./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 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. 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 ) . ")"; } $ ./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))