Problem 59

Problem 59 - Project Euler
また問題文の解釈からつまづいた.
まずXORが何か分からなかっただろ(何
ASCIIコードも調べただろ(何
それはともかく,Rで10進数の数値を入力してXORしてくれる関数ってないのかな.あとASCIIコードと文字の相互変換してくれるような関数も.これCの方が楽かな.あまり書けないけど.

library(gmp)
cipher <- scan("cipher1.txt", sep=",")

to.binary.vec <- function(x){
  tmp <- logical(8)
  bin <- as.logical(as.numeric(strsplit(as.character.bigz(x,2),"")[[1]]))
  tmp[(9-length(bin)):8] <- bin
  tmp
}

vec.xor <- function(a,b){
  xor(to.binary.vec(a), to.binary.vec(b))
}

num.xor <- function(a,b){
  if(is.na(a)) return(0)
  lgcl.ans <- vec.xor(a,b)
  sum(rev(lgcl.ans)*2^(0:(length(lgcl.ans)-1)))
}

char <- c(" ", ",", ".", 0:9, LETTERS, letters, "(", ")", "'", ";", "!")
ascii <- c(32,  44,  46,48:57, 65:90, 97:122, 40, 41, 39, 59, 33)

keycnt <- numeric(3)
key.candy <- numeric(3)
for(i in 97:122){
  cnt <- numeric(3)
  for(j in seq(1,length(cipher),by=3)){
    for(l in 1:3){
      if(num.xor(cipher[j+l-1],i) == 32) cnt[l] <- cnt[l] + 1
    }
  }
  for(k in 1:3){
    if(cnt[k] > keycnt[k]){
      keycnt[k] <- cnt[k]
      key.candy[k] <- i
    }
  }
}
key.candy

answer <- 0
for(i in seq(1,length(cipher), by=3)){
  for(j in 0:2){
    answer <- answer + num.xor(cipher[i+j],key.candy[j+1])
  }
}
answer

decipher <- character(length(cipher))
for(i in seq(1, length(cipher), by=3)){
  for(j in 0:2){
    asc <- num.xor(cipher[i+j], key.candy[j+1])
    decipher[i+j] <- char[ascii==asc]
  }
}

decip.txt <- character(1)
for(i in 1:length(cipher)){
  decip.txt <- paste(decip.txt, decipher[i], sep="")
}
decip.txt

別にこの問題はテキストに戻さなくてもいいんだけど気になったので一応戻した.
てかあっちの人はこの文章大好きだな.鍵の一文字目で予想ついたわw