DEV Community

Simon Green
Simon Green

Posted on

Weekly Challenge: Digital reduction

Weekly Challenge 359

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: Digital Root

Task

You are given a positive integer, $int.

Write a function that calculates the additive persistence of a positive integer and also return the digital root.

  • Digital root is the recursive sum of all digits in a number until a single digit is obtained.
  • Additive persistence is the number of times you need to sum the digits to reach a single digit.

My solution

Starting this week, I'm going to turn off VS Code Copilot when completing the challenge. As AI takes over the task of code completion, it's still a good exercise to do things by hand so as I don't depend on it.

For this tasks, I create two variables. The first is called persistence and starts at 0. The second variable is called digital_root and starts with the supplied integer. This is called number in Python, as int is a reserved word.

I then have a loop that continues until digital_root is a single digit. Breaking down the line:

  • str(digital_root) will convert the digital_root integer to a string
  • d for d in will convert each character to a single digit
  • map(int(... will convert the digit back to an integer
  • sum(... will add the single digit

I also increment the persistence value by one. I end by returning the two values. The main function is responsible for displaying the text as per the examples.

def get_digital_root(number: int) -> tuple[int, int]:
    if number <= 0:
        raise ValueError("You must provide a positive integer")

    persistence = 0
    digital_root = number

    while len(str(digital_root)) > 1:
        digital_root = sum(map(int, (d for d in str(digital_root))))
        persistence += 1

    return persistence, digital_root
Enter fullscreen mode Exit fullscreen mode

The Perl solution follows the same logic. Perl doesn't make a distinction between string and integers (yes, there are some exceptions to this rule), but does require the split function to break the digital_root value into individual digits.

use List::Util 'sum';

sub main ($int) {
    my $persistence  = 0;
    my $digital_root = $int;

    # Keep iterating until we have a single digital
    while ( length($digital_root) > 1 ) {
        $digital_root = sum( split( //, $digital_root ) );
        $persistence++;
    }

    say "Persistence  = $persistence";
    say "Digital Root = $digital_root";
Enter fullscreen mode Exit fullscreen mode

Examples

$ ./ch-1.py 38
Persistence  = 2
Digital Root = 2

$ ./ch-1.py 7
Persistence  = 0
Digital Root = 7

$ ./ch-1.py 999
Persistence  = 2
Digital Root = 9

$ ./ch-1.py 1999999999
Persistence  = 3
Digital Root = 1

$ ./ch-1.py 101010
Persistence  = 1
Digital Root = 3
Enter fullscreen mode Exit fullscreen mode

Task 2: String Reduction

Task

You are given a word containing only alphabets.

Write a function that repeatedly removes adjacent duplicate characters from a string until no adjacent duplicates remain and return the final word.

My solution

This is a duplicate (albeit slightly re-worded) of the first task in week 340. Therefore I copy and pasted that code, and renamed the function. See my original blog post on how this was solved.

Examples

$ ./ch-2.py aabbccdd
""

$ ./ch-2.py abccba
""

$ ./ch-2.py abcdef
"abcdef"

$ ./ch-2.py aabbaeaccdd
"aea"

$ ./ch-2.py mississippi
"m"
Enter fullscreen mode Exit fullscreen mode

Top comments (0)