Broken digits
Published: 2024-06-30 07:09:53

## Weekly Challenge 275

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-275/), [My solutions](https://github.com/manwar/perlweeklychallenge-club/tree/master/challenge-275/sgreen)

## Task 1: Broken Keys

### Task

You are given a sentence, `$sentence` and list of broken keys `@keys`.

Write a script to find out how many words can be typed fully.

### My solution

Two relativity straight forward tasks this week. For this task, I split the `str` variable into the `words` list (array in Perl), converting the string to lower case. I also convert the `keys` list to lower case too. I have a variable `count` that is original set to zero. This is the number of words that don't contain a broken key.

```python
def broken_keys(s: str, keys: list) -> int:
    words = s.lower().split(' ')
    keys = [key.lower() for key in keys]
    count = 0
```

I then loop through each `words` value as the variable `word`. If none (not any) of the letters in `keys` is in `word`, I add one to the `count` variable.

```python
    for word in words:
        if not any(key in word for key in keys):
            count += 1

    return count
```

### Examples

```bash
$ ./ch-1.py "Perl Weekly Challenge" l a
0

$ ./ch-1.py "Perl and Raku" a
1

$ ./ch-1.py "Well done Team PWC" l o
2

$ ./ch-1.py "The joys of polyglottism" T
2
```

## Task 2: Replace Digits

### Task

You are given an alphanumeric string, `$str`, where each character is either a letter or a digit.

Write a script to replace each digit in the given string with the value of the previous letter plus (digit) places.

### My solution

There are two unanswered questions that the examples don't shed a light on.

1. What happens when a number appears before the first letter? I treat this as an error, and exit the program with an appropriate message.
1. What is the output of `z1`? If this occurs, I roll over the alphabet. For example `z1` is `a`, `y3` is `b`.

I start with the following variables:
* `current_letter` which is the last seen letter (default is `None`)
* `solution` which represents the solution. It starts as an empty string.
* `alphabet` is a string of the 26 letters of the alphabet.

I loop through each letter of the `str` value, as the variable `char`. If it is a number, I calculate the index of the last letter, add `char` (as an integer) to it, and add the corresponding letter of the alphabet to the `solution` string. If it is a letter, I add it to the `solution` string and update `current_letter`.

```python
def replace_digits(s: str) -> str:
    current_letter = None
    solution = ''
    alphabet = string.ascii_lowercase

    for char in s:
        if char.isdigit():
            if current_letter is None:
                raise ValueError('The first number must follow a letter.')
            solution += alphabet[(alphabet.index(current_letter) +
                                  int(char)) % 26]
        else:
            solution += char
            current_letter = char

    return solution
```

### Examples

```bash
$ ./ch-2.py a1c1e1
abcdef

$ ./ch-2.py a1b2c3d4
abbdcfdh

$ ./ch-2.py b2b
bdb

$ ./ch-2.py a16z
abgz
```