perlgolf hole - Digital Root

Hole type: subroutine

Adding up the digits of a non-negative integer produces a number:

1234567 -> 1+2+3+4+5+6+7 -> 28

Adding up those digits produces another:

28 -> 2+8 -> 10

Repeating this process until only a single digit is left produces a checksum known as a digital root:

10 -> 1+0 -> 1

Write a subroutine to compute the digital root of any non-negative integer argument.


sub hole {$_[0]=eval join'+',split//,$_[0]while$_[0]>9;$_[0]}50
sub hole {($_)=@_;s/(\d)(\d)/$1+$2/ge while$_>9;$_}40
sub hole {$_=pop;1while s/(\d)(\d)/$1+$2/ge;$_}36


The easy part is adding the digits. The tricky part is separating the digits, and knowing when to stop. The first solution uses a well-known approach; split the digits, join them with '+', and eval the result.

The second and third solutions also use eval, but in the form of /e, and repeatedly add two digits at a time. The second solution stops when the result is less than or equal to 9. The third solution improves this by using the substitution as the conditional; the substitution will return false when there is only one digit left.