虫食い算

面白い問題を教えてもらった。
虫食い算をRで総当りで解くらしい。

S E N D
+) M O R E
M O N E Y

行列構造を保って演算するようにがんばる。

f1 <- function(){
	library(gtools)
	perm <- permutations(10, 8, v=0:9, set=TRUE, repeats.allowed=FALSE) # パターンの発生
	#perm <- subset(perm, perm[,1]>0) # S は0でないことはわかる。
	#perm <- subset(perm, perm[,5]>0) # M もそうだがこれやると遅い。
	idx <- list(c(1,2,3,4), c(5,6,7,2), c(5,6,3,2,8)) # SENDMOREMONEY に対応
	mat <- matrix(10^rev(seq(max(sapply(idx, length)))-1), nr=nrow(perm), nc=max(sapply(idx, length)), byrow=TRUE)
	res <- mapply(function(x) rowSums(perm[,x] * mat[, (ncol(mat)-length(x)+1):ncol(mat)]), idx)
	perm[which(rowSums(res[, 1:2]) == res[, 3]),]
}
f()
[1] 9 5 6 7 1 0 8 2

14秒くらいかかる。