0

I have a numeric vector, let's call it v, and I want to evaluate the result of XORing all of its values together, i.e. I want to find v[1] XOR v[2] XOR v[3] ...

I have the binary bitwise XOR function bitXor from the package bitops. Is there a neat bit of code I can use that acts like a *apply function and does the complete XORing in one go without using an explicit loop? I'm happy with both a solution that works for any suitable binary function, or if there's an implementation of more-than-binary XOR that I've missed.

jaimedash
  • 2,683
  • 17
  • 30
ConMan
  • 141
  • 3
  • Is this XOR between adjacent values only? Or between any combination of values in the vector? – Simon Apr 21 '16 at 04:09
  • Across all the values in the vector. In other words, I want to input the vector, and return the single value that is the result of successively XORing the elements. Like if v = c(101b, 110b, 11b) then I want 101 XOR 110 XOR 011 = 000 = 0. – ConMan Apr 21 '16 at 04:12
  • 2
    How is `c(101b, 110b, 11b)` a valid vector? And do you just want `Reduce(bitXor, c(101, 110, 11))` ? – thelatemail Apr 21 '16 at 04:20
  • Sorry misread! Need to format... – jaimedash Apr 21 '16 at 04:29
  • 1
    But, in any case @thelatemail is correct about `Reduce` which will successively apply a a command with two arguments to a vector. Try `Reduce(bitXor, c(5, 6, 3))` (using the decimal versions of your example) – jaimedash Apr 21 '16 at 04:40
  • @thelatemail no worries. it's all a bit convoluted. essentially the Q boils down to this: https://stackoverflow.com/questions/11645090/repeatedly-re-apply-2-argument-function-using-result-of-previous-call/11645640#11645640 PS you should put your `Reduce` snippet as the answer – jaimedash Apr 21 '16 at 05:01

1 Answers1

2

First of all, stealing the binary conversion function from here - Convert binary string to binary or decimal value

BinToDec <- function(x) {
    sum(2^(which(rev(unlist(strsplit(as.character(x), "")) == 1))-1))
}

So, you can then do:

vals <- c("101", "110", "11")
Reduce(bitXor, vapply(vals, BinToDec, FUN.VALUE=numeric(1)) )
#[1] 0

Or to see each step, you can do:

Reduce(bitXor, vapply(vals, BinToDec, FUN.VALUE=numeric(1)), accumulate=TRUE)
#[1] 5 3 0

Which is equivalent to:

c(bitXor(5,0), bitXor(5,6), bitXor(bitXor(5,6),3))
#[1] 5 3 0
Community
  • 1
  • 1
thelatemail
  • 91,185
  • 12
  • 128
  • 188
  • The converting to string bit isn't really necessary, since I'll actually be working in straight numbers (I just used the binary values in my comment to make it clearer what was happening, although it looks like that failed). However, the Reduce function is *exactly* what I wanted, so thank you! – ConMan Apr 21 '16 at 23:48