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.
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 thedigital_rootinteger to a string -
d for d inwill 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
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";
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
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"
Top comments (0)