The Indian mathematician D.R. Kaprekar first described ‘self-born’ numbers or self-numbers in a small article in 1949. Here is the sequence of the first 12 self-numbers:
1 3 5 7 9 20 31 42 53 64 75 86 …
I shall describe what these numbers are, and how to find and test for them in R.
The origins of self-numbers are in a process Kaprekar called digitadition. This is the summing of all the digits of a positive integer, to the integer. For example:
47 ⇒ 47 + 4 + 7 = 58
A digitadition series can be constructed by repeating the digitadition process to each number infinitely.
47 58 71 79 95 …
These functions to make a digitadition series are trivial to make in R - although I’d imagine that these functions could be improved upon! First we need to make a function to extract the digits of any number:
digits <- function(x){as.integer(substring(x, seq(nchar(x)), seq(nchar(x))))}
digits(47)
## [1] 4 7
digits(1059)
## [1] 1 0 5 9
Related to this function, we can create a function to find the digital root of any number, which is found by summing the digits of a positive integer and then summing this result if it is longer than one digit in length. Once the sum is only one digit, that is the digital root.
47 ⇒ 4 + 7 = 11 ⇒ 1 + 1 = 2
digit.root <- function(n){
x<-n
while(TRUE) {
x <- sum(digits(x))
if(length(digits(x)) == 1 )
break
}
return(x)
}
digit.root(47)
## [1] 2
digit.root(1059)
## [1] 6
We can use the digits
function to find the next generated number in a sequence:
generated <- function(x){ x + sum(digits(x))}
generated(47)
## [1] 58
generated(1059)
## [1] 1074
And if we apply this function recurively, we can find any digitadition series of length N.
digitadition <- function(x,N) { c(x, replicate(N-1, x <<- generated(x))) }
digitadition(47, 5)
## [1] 47 58 71 79 95
digitadition(1059, 7)
## [1] 1059 1074 1086 1101 1104 1110 1113
In one of his small papers Kaprekar noted that if you subtract the first number from the last number of any digitadition series and then add the sum of the digits of the last number, that that will always be equal to the sum of all the digits in the digitadition series. Kaprekar wrote: “Is this not a wonderful new result? …The Proof of all this rule is very easy and I have completely written it with me. But as soon as the proof is seen the charm of the whole process is lost, and so I do not wish to give it just now.”
We can check this with a few examples:
z <- digitadition(47,5)
z
## [1] 47 58 71 79 95
(z[length(z)] - z[1]) + sum(digits(z[length(z)])) # 95 - 47 + 4 + 7 = 62
## [1] 62
sum(apply(sapply(z, digits),2,sum)) #sum of all digits in digitidation sequence = 62
## [1] 62
We can turn this into a quick test function, returning the two computed values for any digitadition series we choose:
digitadition.test <- function(x,N){
z <- digitadition(x,N)
z1 <- (z[length(z)] - z[1]) + sum(digits(z[length(z)]))
z2 <- sum(apply(sapply(z, digits),2,sum))
return(c(z1,z2))
}
digitadition.test(47,5)
## [1] 62 62
digitadition.test(1059,7)
## [1] 60 60
digitadition.test(334,6)
## [1] 72 72
digitadition.test(101013,15)
## [1] 168 168
That’s pretty cool !
Some numbers are more likely to be generated than others. Although no number underneath 100 can be generated by more than one generator (remember that e.g. 47 is the generator whereas 58 is the generated number), the first number to have more than one generator is 101. A number with more than one generator is called a junction number.
91 ⇒ 91 + 9 + 1 = 101
100 ⇒ 100 + 1 + 0 + 0 = 101
I have not yet played around with a function to find all possible generators for any given number, but I’m sure that it’s possible, although it might require lots of computer power! The smallest junction number with 3 generators is 10,000,000,000,001 - generated by 10,000,000,000,000, 9,999,999,999,901 and 9,999,999,999,892.
Kaprekar himself found the smallest junction number with four generators and it has 25 digits - 1,000,000,000,000,000,000,000,102 !
Now we are ready to finally discuss self-numbers! These numbers are simple those numbers that do not have any generator ! How do we find these numbers. One laborious method would be to simulate thousands of digitadition series to see which numbers never appear. Here I’m starting with numbers 1 to 50 and making digitadition series of between 1 and 50 in length. I’ll just focus on those numbers that are under 50 that appear in these series:
res <- NULL
for(i in 1:50){
for(j in 2:50){
tmp <- digitadition(i,j)
IND <- 50*(i-1) + (j-1) - (i-1) #to index results
res[IND] <- tmp[length(tmp)]
}
}
df <- data.frame(number = unlist(res), generator=rep(1:50, each=49), N=2:50)
table(df$number)[as.numeric(names(table(df$number)))<=50] #look at numbers 1:50
##
## 2 4 6 8 10 11 12 13 14 15 16 17 18 19 21 22 23 24 25 26 27 28 29 30 32
## 1 2 1 3 1 2 2 3 1 3 4 4 1 2 4 1 5 5 5 2 2 6 3 6 6
## 33 34 35 36 37 38 39 40 41 43 44 45 46 47 48 49 50
## 7 3 1 3 7 7 8 4 4 2 5 4 5 8 1 8 3
If we look at this table, we can see that certain numbers under 50 appear quite a lot but some are missing. We can find these easily enough:
temp <- table(df$number)[as.numeric(names(table(df$number)))<=50]
setdiff(1:50, as.numeric(names(temp)))
## [1] 1 3 5 7 9 20 31 42
We pretty exhaustively tested all possible digitadition sequences that numbers under 50 could possibly appear in and the only numbers that we could not detect were 1, 3, 5, 7, 9, 20, 31, and 42. These are, in fact, the only self-numbers under 50.
You may have realized that this is actually a pretty terrible way to go about finding self-numbers. Fortunately, Kaprekar came up with a demonstration that the following method can be used to determine if a number is a self-number or not. More information is available here.
I adapted this demonstration into the following function that will test whether a number is a so-called self-born number:
h.n <- function(x){
if ((x %% 2 == 0)==T) {X <- x/2 }
else
X <- (x+9)/2
return(X)
}
rn <- function(n) {1+((n-1) %% 9)}
self.test <- function(n){
hn <- h.n(rn(n))
k <- 0:length(digits(n))
res <- lapply(k, function(k) sum(digits(abs(n-hn-(9*k)))) != hn + (9*k))
if (FALSE %in% unlist(res) == T) {out <- FALSE}
else
{out <- TRUE}
return(out)
}
self.test(20)
## [1] TRUE
self.test(25)
## [1] FALSE
self.test(42)
## [1] TRUE
self.test(43)
## [1] FALSE
self.test(121)
## [1] TRUE
self.test(122)
## [1] FALSE
Just as a quick demonstration of the sorts of things that can be explored, let’s look at the distribution of self-numbers between 1 and 1,000,000.
x<-1:100000
selfies <- sapply(x, self.test)
selfies.df <- data.frame(n=1:100000, value = selfies+0)
selfies.df$cume <- cumsum(selfies.df$value)
library(ggplot2)
ggplot(selfies.df, aes(n, cume)) + geom_path() + theme_bw()
As can be seen from this graph, the rate at which self-numbers appear is pretty consistent. Out of the numbers 1 to 100,000 it turns out that 9.78% of numbers are self-born.
Kaprekar called numbers that are both self-numbers and primes self-primes. Let’s look for these up to 1,000.
is.prime <- function(num) {
if (num == 2) {
TRUE
} else if (any(num %% 2:(num-1) == 0)) {
FALSE
} else {
TRUE
}
}
selfprime <- selfies.df[1:1000, ]
selfprime$primes <- sapply(1:1000, is.prime)
selfprime[selfprime$value==1 & selfprime$primes == TRUE,]$n
## [1] 3 5 7 31 53 97 211 233 277 367 389 457 479 547 569 613 659
## [18] 727 839 883 929
Here they are!:
3 5 7 31 53 97 211 233 277 367 389 457 479 547 569 613 659 727 839 883 929 …
If you have any feedback please get in touch. Probably the fastest way is to go to my twitter page.