Lucky values
Tags: perl, python, theweeklychallenge
Published: 2024-01-14 12:08:20

## Weekly Challenge 251

Each week Mohammad S. Anwar sends out [The Weekly Challenge](https://theweeklychallenge.org/), 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](https://theweeklychallenge.org/blog/perl-weekly-challenge-251/), [My solutions](https://github.com/manwar/perlweeklychallenge-club/tree/master/challenge-251/sgreen)

## Task 1: Concatenation Value

### Task

You are given an array of integers, `@ints`.

Write a script to find the concatenation value of the given array.

The concatenation of two numbers is the number formed by concatenating their numerals.

For example, the concatenation of 10, 21 is 1021. The concatenation value of `@ints` is initially equal to 0.
Perform this operation until `@ints` becomes empty:

* If there exists more than one number in `@ints`, pick the first element and last element in `@ints` respectively and add the value of their concatenation to the concatenation value of `@ints`, then delete the first and last element from `@ints`.
* If one element exists, add its value to the concatenation value of `@ints`, then delete it.

### My solution

This is relatively straight forward, although concatenating integers in Python is a little clunky (need to convert them to string and then back to integers).

I start with the two variables. `solution` holds the running sum, and `half` is the integer value of dividing the length of `@ints` by two.

If we have an odd number of elements, I add the middle number (index `half`) to the `solution` value.

```python
if len(ints) % 2 == 1:
    solution += ints[half]
```

I then combine the concatenation of the remaining integer pairs, starting with first and last, then second and second last, and so on.

```python
for i in range(half):
    solution += int(str(ints[i]) + str(ints[-1-i]))
```

### Examples

```bash
$ ./ch-1.py 6 12 25 1
1286

$ ./ch-1.py 10 7 31 5 2 2
489

$ ./ch-1.py 1 2 10
112
```

## Task 2: Lucky Numbers

### Task

You are given a `m × n` matrix of distinct numbers.

Write a script to return the lucky number, if there is one, or `-1` if not.

A lucky number is an element of the matrix such that it is
the minimum element in its row and maximum in its column.

### My solution

This is an interesting challenge. When writing this blog (and after writing my code), I was convinced that it was possible to have two lucky numbers. Despite my best efforts on my whiteboard, I'm now of the opinion that it is not possible, so that removed some complexity from the final code.

For this task, I take the input as a JSON array of arrays, and store this in the variable `matrix`. The first thing I do is check that all the rows have the same number of columns.

```python
for r in range(1, rows):
    if len(matrix[r]) != cols:
        raise ValueError(f'Row {r} has different number of columns')
```

I then calculate the max value of each column, and store this in the `column_max` variable.

```python
column_max = []
for c in range(cols):
    column_max.append(max(map(lambda i: i[c], matrix)))
```

The meaty part of the function is iterating each row. Here I set the `row_min` value to the minimum value. I then check for any cells that have the minimum value and the value from `column_max` for this position is also the minimum value. If it is, I set the `solution` variable and exit the loop.

```python
for r in matrix:
    row_min = min(r)
    if any(True for i, value in enumerate(r)
           if value == row_min and column_max[i] == value):
        solution = row_min
        break
```

### Examples

```bash
$ ./ch-2.py "[ [ 3,  7,  8], [ 9, 11, 13], [15, 16, 17] ]"
15

$ ./ch-2.py "[ [ 1, 10,  4,  2], [ 9,  3,  8,  7], [15, 16, 17, 12] ]"
12

$ ./ch-2.py "[[7, 8], [1, 2]]"
7
```