DEV Community

Simon Green
Simon Green

Posted on

Weekly Challenge: Oddly small

Weekly Challenge 3××

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: Smaller Than Current

Task

You are given an array of numbers, @num1.

Write a script to return an array, @num2, where $num2[i] is the count of all numbers less than or equal to $num1[i].

My solution

This one is relatively straight forward. I iterate through the input list (array in Perl) with the variable number. I then count the number of elements in the input list that are equal to or less than that number. I subtract one from that count to exclude the number itself.

def smaller_than_current(numbers: list) -> list:
    solution = []

    for number in numbers:
        solution.append(sum(1 for n in numbers if n <= number) - 1)

    return solution
Enter fullscreen mode Exit fullscreen mode

Examples

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

$ ./ch-1.py 7 7 7 7
[3, 3, 3, 3]

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

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

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

Task 2: Odd Matrix

Task

You are given row and col, also a list of positions in the matrix.

Write a script to perform action on each location (0-indexed) as provided in the list and find out the total odd valued cells.

For each location (r, c), do both of the following:

  1. Increment by 1 all the cells on row r.
  2. Increment by 1 all the cells on column c.

My solution

After last week's second task where Copilot wrote the code based on my test cases, I'm changing tack and writing the code first. As expected, Copilot is less useful and only assisted in code completion.

For this task, I take the first two values of the command line parameters as the rows and cols value. I then take the rest as a pair of points.

def main():
    array = [int(n) for n in sys.argv[1:]]
    row = array.pop(0)
    col = array.pop(0)
    points = [(array[i], array[i + 1]) for i in range(0, len(array), 2)]

    result = odd_matrix(row, col, points)
    print(result)
Enter fullscreen mode Exit fullscreen mode

I start by creating a dataclass called Point. It takes two variables, x and y as input. I have a function in it called score. It takes the input row and col and returns the score for this point at that position. It will be 2 if the x and y values are the same, 1 if only one is the same or 0 otherwise.

from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int

    def score(self, row:int, col:int) -> int:
        if row == self.x and col == self.y:
            return 2
        if row == self.x or col == self.y:
            return 1

        return 0
Enter fullscreen mode Exit fullscreen mode

This then makes the rest of the code easier to follow. I start by creating a list of Point objects from the input matrix. I then iterate through each cell in the matrix.

For each iteration, I calculate the score for that cell. If it is odd, I increment the odd_cells variable. I finish by returning the value of odd_cells.

def odd_matrix(rows:int, cols:int, points_list: list) -> int:
    points = [Point(x, y) for x, y in points_list]
    odd_cells = 0

    for row in range(rows):
        for col in range(cols):
            score = 0
            for point in points:
                score += point.score(row, col)

            if score % 2 == 1:
                odd_cells += 1

    return odd_cells
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-2.py 2 3 0 1 1 1
6

$ ./ch-2.py 2 2 1 1 0 0
0

$ ./ch-2.py 3 3 0 0 1 2 2 1
0

$ ./ch-2.py 1 5 0 2 0 4
2

$ ./ch-2.py 4 2 1 0 3 1 2 0 0 1
8
Enter fullscreen mode Exit fullscreen mode

Top comments (0)