Somayeh Ghazalbash
Somayeh Ghazalbash

Reputation: 65

How do I Compute Binary String Permutations in R?

I have a binary string like this:

0010000

I'd like to have all these permutations:

1010000
0110000
0011000
0010100
0010010
0010001

Is there anybody know which function in R could give me these results?

Upvotes: 1

Views: 326

Answers (3)

G. Grothendieck
G. Grothendieck

Reputation: 269526

We assume that the problem is to successively replace each 0 in the input with a 1 for an input string of 0's and 1's.

Replace each character successively with a "1", regardless of its value and then remove any components of the result equal to the input. No packages are used.

input <- "0010000"

setdiff(sapply(1:nchar(input), function(i) `substr<-`(input, i, i, "1")), input)
## [1] "1010000" "0110000" "0011000" "0010100" "0010010" "0010001"

Update: Have completely revised answer.

Upvotes: 1

alistaire
alistaire

Reputation: 43334

R has functions for bitwise operations, so we can get the desired numbers with bitwOr:

bitwOr(16, 2^(6:0))
#> [1] 80 48 16 24 20 18 17

...or if we want to exclude the original,

setdiff(bitwOr(16, 2^(6:0)), 16)
#> [1] 80 48 24 20 18 17

However, it only works in decimal, not binary. That's ok, though; we can build some conversion functions:

bin_to_int <- function(bin){
    vapply(strsplit(bin, ''), 
           function(x){sum(as.integer(x) * 2 ^ seq(length(x) - 1, 0))}, 
           numeric(1))
}

int_to_bin <- function(int, bits = 32){
    vapply(int, 
           function(x){paste(as.integer(rev(head(intToBits(x), bits))), collapse = '')},
           character(1))
}

Now:

input <- bin_to_int('0010000')

output <- setdiff(bitwOr(input, 2^(6:0)),
                  input)

output
#> [1] 80 48 24 20 18 17

int_to_bin(output, bits = 7)
#> [1] "1010000" "0110000" "0011000" "0010100" "0010010" "0010001"

Upvotes: 2

jrlewi
jrlewi

Reputation: 506

library(stringr)   
bin <- '0010000'
ones <- str_locate_all(bin, '1')[[1]][,1]
zeros <- (1:str_length(bin))[-ones]
sapply(zeros, function(x){
str_sub(bin, x, x) <- '1'
bin
})
[1] "1010000" "0110000" "0011000" "0010100" "0010010" "0010001"

Upvotes: 1

Related Questions