List of all 1 numbers that differ by exactly 1 digit

Let's say I have a number:

a<-11121

      

I would like to list all other length numbers a

that differ by exactly 1 digit. Also, suppose the values ​​can only take 1 and 2

Solution required:

21121
12121
11221
11122
11111

      

+3


source to share


2 answers


Here are some solutions:

1) replace_ith

replaces i-th digit in a

with 1 if it is 2 and 2 if it is 1. Apply this to each digit:

replace_ith <- function(i, a) {
  ch <- strsplit(as.character(a), "")[[1]]
  ch[i] <- if (ch[i] == "1") "2" else "1"
  as.numeric(paste(ch, collapse = ""))
}

a <- 11121
sapply(1:nchar(a), replace_ith, a)

      

giving:

[1] 21121 12121 11221 11111 11122

      



2) Here is the second possible implementation replace_ith

:

replace_ith <- function(i, a) {
  a <- as.character(a)
  substr(a, i, i) <- if (substr(a, i, i) == "1") "2" else "1"
  as.numeric(a)
}

      

3) Here is the third implementation. The three terms are digits before the i-th digit times 10^i

, the inverse of the i-th digit times 10^(i-1)

and the digits after the i-th digit:

replace_ith <- function(i, a) {
  (a %/% 10^i) * 10^i + 10^(i-1) * ( 3 - (a %% 10^i) %/% 10^(i-1) ) + a %% 10^(i-1)
}

      

+4


source


Here the answer is done purely numerically and vectorized as a single line:

(2 * a %/% (b <- 10^(1:5))) * b +
  ((2 * a) %% (b / 10)) +
  0.3 * b - a

      

It works by zeroing each digit 2 * a

in turn and inserting 3 in their place, which will flip from 2 to 1, or vice versa. It creates a variable b

to shorten the code a bit. This can be removed by replacing each b

with its definition or by calling an expression inside local()

.

Here's another, using the pipe of magrittr

and matrix operator :

a %>% as.character %>% strsplit("") %>%
  unlist %>% as.numeric %>% matrix(5, 5) %>%
  `diag<-`(., 3 - diag(.)) %>% t %>% `%*%`(10 ^ (4:0))

      



And here's a neater version of the second, using purely numeric methods:

a %>% rep(5) %>% outer(4:0, function(x, y) x %/% (10 ^ y) %% 10) %>%
  `diag<-`(., 3 - diag(.)) %>% `%*%`(10 ^ (0:4))

      

And another one using binary and using a package R.utils

:

as.character(a) %>% strsplit("") %>% {.[[1]] == "2"} %>%
  multiply_by_matrix(2 ^ (4:0)) %>% bitwXor(2 ^ (4:0)) %>%
  intToBin %>% as.integer(.) + 11111

      

+1


source







All Articles