DEV Community

Simon Green
Simon Green

Posted on

Weekly Challenge: Strings and Arrays

Weekly Challenge 322

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. It's a great way for us all to practice some coding.

Challenge, My solutions

Task 1: String Format

Task

You are given a string and a positive integer.

Write a script to format the string, removing any dashes, in groups of size given by the integer. The first group can be smaller than the integer but should have at least one character. Groups should be separated by dashes.

My solution

There is probably a way to do this using regular expression. However that would take away the readability of the solution.

For this task, I start by removing all the existing dashes in the input_string (and yes, with regular expressions for the Perl solution). I then calculate the start variable by taking the modulus of the length of input_string from size.

If this is not zero, we need to capture the first part of the string (the first start letters), and put this in the parts list (array in Perl).

I then have a loop from start to the length of input_string, increasing by size each time. For each iteration, I add to the parts list with the characters from pos to pos + size -1.

Finally, I join the parts list with hyphens to produce the final solution.

def string_format(input_string: str, size: int) -> str:
    input_string = input_string.replace("-", "")

    start = len(input_string) % size
    parts = []


    if start:
        parts.append(input_string[0:start])

    for pos in range(start, len(input_string), size):
        parts.append(input_string[pos:pos+size])

    return '-'.join(parts)
Enter fullscreen mode Exit fullscreen mode

The Perl solution follows the same logic, but uses the substr function to retrieve parts of the string.

sub main ( $input_string, $size ) {
    $input_string =~ s/-//g;

    my $start = length($input_string) % $size;
    my @parts = ();


    if ($start) {
        push @parts, substr( $input_string, 0, $start );
    }

    for ( my $pos=$start; $pos < length($input_string); $pos+=$size ) {
        push @parts, substr( $input_string, $pos, $size );
    }

    say join( '-', @parts );
}
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-1.py ABC-D-E-F 3
ABC-DEF

$ ./ch-1.py A-BC-D-E 2
A-BC-DE

$ ./ch-1.py A-B-CD-E 4
A-BCDE
Enter fullscreen mode Exit fullscreen mode

Task 2: Rank Array

Task

You are given an array of integers.

Write a script to return an array of the ranks of each element: the lowest value has rank 1, next lowest rank 2, etc. If two elements are the same then they share the same rank.

My solution

This is relatively straight forward, and two lines in Python. I create a list called sorted_list which has the unique integers sorted numerically. By converting the list to a set, we remove any duplicate integers.

I then use list comprehension to find the index of each integer in ints in sorted_list. Each value is incremented by 1, as the solution is one-based.

def rank_array(ints: list) -> list:
    sorted_list = sorted(set(ints))

    return [sorted_list.index(i)+1 for i in ints]
Enter fullscreen mode Exit fullscreen mode

The Perl solution is a little more involved, as it does not have list comprehension. Well that's not entirely true, there is the map function.

For the Perl solution, I start by creating sorted_array which has the unique integers sorted numerically. I then have a foreach loop which uses the first_index function to find the position of that integer in the sorted_array array. Like with the Python solution, we increment the value by one.

sub main (@ints) {
    my @sorted_array = sort { $a <=> $b } uniq(@ints);
    my @solution     = ();

    foreach my $int (@ints) {
        my $idx = first_index { $_ == $int } @sorted_array;
        push @solution, $idx + 1;
    }

    say '(', join( ', ', @solution ), ')';
}
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-2.py 55 22 44 33
[4, 1, 3, 2]

$ ./ch-2.py 10 10 10
[1, 1, 1]

$ ./ch-2.py 5 1 1 4 3
[4, 1, 1, 3, 2]
Enter fullscreen mode Exit fullscreen mode

Top comments (0)