Self Numbers

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.




Digitadition

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




A Peculiar Property of Digitadition Series

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 !




Generated Numbers

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 !




Self-Numbers

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


Distribution of Self-Numbers

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.




Self-Primes

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.