2015-06-28 1 views
3

Допустит, у меня есть номер:Список всех 1 числа, которые различаются ровно 1 цифра

a<-11121 

Я хотел бы перечислить все другие номера длин a, которые отличаются ровно 1 разряд. Кроме того предполагается, что значения могут принимать только 1 и 2

Искомое решение будет:

21121 
12121 
11221 
11122 
11111 
+0

Что относительно '11111'? – Molx

+0

да, извините, я добавил его :) – user1984076

ответ

4

Вот некоторые решения:

1)replace_ith заменяет ю цифру в a с 1, если это 2 и 2, если это 1. Применить это к каждой цифре:

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) 

подача:

[1] 21121 12121 11221 11111 11122 

2) Вот второй возможный вариант осуществления 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) Вот третья реализация. Три члена являются цифрами до го разряда раза 10^i, обращенно-го разряда раза 10^(i-1) и цифры после го разряда:

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

Вот ответ делается чисто числена и vectorised одной строки:

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

Он работает, обнуляя каждую цифру 2 * a по очереди и помещая 3 вместо них, которая будет переворачиваться с 2 на 1 или наоборот. Он создает переменную b, чтобы немного сократить код. Это можно удалить, заменив каждое b своим определением или вызвав выражение в local().

Вот еще с помощью оператора трубы из magrittr и матриц:

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

А вот аккуратнее версия второго с использованием чисто численных методов:

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

И еще с помощью бинарных и с использованием пакета R.utils :

as.character(a) %>% strsplit("") %>% {.[[1]] == "2"} %>% 
    multiply_by_matrix(2^(4:0)) %>% bitwXor(2^(4:0)) %>% 
    intToBin %>% as.integer(.) + 11111 
Смежные вопросы