DEV Community

Simon Green
Simon Green

Posted on

Weekly Challenge: New Year, New Challenges

Weekly Challenge 354

Happy New Years everyone.

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: Min Abs Diff

Task

You are given an array of distinct integers.

Write a script to find all pairs of elements with the minimum absolute difference.

Rules (a,b):

  1. a, b are from the given array.
  2. a < b
  3. b - a = min abs diff any two elements in the given array

My solution

This is relatively straight forward. I start by sorting the array numerically. I create two variables. The result list (array in Perl) will store matching pairs. min_abs_diff will store the numerical difference between the two values in a pair, it starts as None (undef in Perl).

def min_abs_diff(ints: list) -> list:
    ints = sorted(ints)
    min_abs_diff = None
    result = []
Enter fullscreen mode Exit fullscreen mode

I then use a loop that starts with 0 to two less than the length of the input list. For each iteration, I compute the difference between the value at the position and following position, using the variable abs_diff.

If the value is less than the current min_abs_diff value (or min_abs_diff is None), I update the variable and set the result array with this pair. If the value is the same, I append this pair to the result array.

    for i in range(len(ints) - 1):
        abs_diff = ints[i + 1] - ints[i]
        if min_abs_diff is None or abs_diff < min_abs_diff:
            min_abs_diff = abs_diff
            result = [[ints[i], ints[i + 1]]]
        elif abs_diff == min_abs_diff:
            result.append([ints[i], ints[i + 1]])

    return result
Enter fullscreen mode Exit fullscreen mode

The Perl code follows the same logic.

Examples

$ ./ch-1.py 4 2 1 3
[[1, 2], [2, 3], [3, 4]]

$ ./ch-1.py 10 100 20 30
[[10, 20], [20, 30]]

$ ./ch-1.py -5 -2 0 3
[[-2, 0]]

$ ./ch-1.py 8 1 15 3
[[1, 3]]

$ ./ch-1.py 12 5 9 1 15
[[9, 12], [12, 15]]
Enter fullscreen mode Exit fullscreen mode

Task 2: Shift Grid

Task

You are given m x n matrix and an integer, $k > 0.

Write a script to shift the given matrix $k times.

My solution

For input from the command line, I take a JSON string as the first value (representing the matrix) and the second value as k.

These are the steps I take to complete the task.

  1. Ensure that the matrix has the same number of columns for each row.
  2. Flatten the list of lists (array of arrays in Perl) into a single list, stored as the flattened_list variable.
  3. If k is not between 0 and one less than the array, take the modulus of the length of flatten_list. For example is k is 7 and there are five items in the flattened list, change it to 2. This will achieve the same result.
  4. Take the last k elements from the list, and append them to the front. In the Python solution, this is stored as rotated_list.
  5. Rebuild the matrix from this new list as the variable new_matrix.
def shift_grid(matrix: list[list[int]], k: int) -> list[list[int]]:
    row_length = len(matrix[0])
    for row in matrix:
        if len(row) != row_length:
            raise ValueError("All rows must have the same length")

    flattened_list = [num for row in matrix for num in row]
    k = k % len(flattened_list)
    rotated_list = flattened_list[-k:] + flattened_list[:-k]

    new_matrix = []
    for i in range(0, len(rotated_list), row_length):
        new_matrix.append(rotated_list[i:i + row_length])

    return new_matrix
Enter fullscreen mode Exit fullscreen mode

Since Perl allows you to remove and append to the same list in a single operation, I use the splice function to achieve this.

sub main ( $matrix_json, $k ) {
    my $matrix = decode_json($matrix_json);

    my $row_length = scalar( @{ $matrix->[0] } );
    foreach my $row (@$matrix) {
        if ( scalar(@$row) != $row_length ) {
            die "All rows must have the same length\n";
        }
    }

    my @flattened_list = map { @$_ } @$matrix;
    $k = $k % scalar(@flattened_list);
    splice( @flattened_list, 0, 0, splice( @flattened_list, -$k ) );

    my @new_matrix = ();
    for ( my $i = 0 ; $i <= $#flattened_list ; $i += $row_length ) {
        push @new_matrix, [ @flattened_list[ $i .. $i + $row_length - 1 ] ];
    }

    say '('
        . join( ",\n ",
            map { '[' . join( ', ', @$_ ) . ']' } @new_matrix )
      . ',)';
}
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-2.py "[[1, 2, 3], [4, 5, 6], [7, 8, 9]]" 1
([9, 1, 2],
 [3, 4, 5],
 [6, 7, 8],)

$ ./ch-2.py "[[10, 20], [30, 40]]" 1
([40, 10],
 [20, 30],)

$ ./ch-2.py "[[1, 2], [3, 4], [5, 6]]" 1
([6, 1],
 [2, 3],
 [4, 5],)

$ ./ch-2.py "[[1, 2, 3], [4, 5, 6]]" 5
([2, 3, 4],
 [5, 6, 1],)

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

Top comments (0)