DEV Community

Simon Green
Simon Green

Posted on

Weekly Challenge: Joining and splitting lists

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

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")
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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";
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 ) . ")";
}
Enter fullscreen mode Exit fullscreen mode

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))
Enter fullscreen mode Exit fullscreen mode

Top comments (0)