元記事の関数の実行時間のほぼ90%は,permutations が占める。
なので,残りの部分を凝ってみても速度向上は望めないので,せめて分かりやすく書いてみるか。
f2 = function() {
library(gtools)
perm = t(gtools::permutations(10, 8))-1
perm = perm[, perm[1, ] != 0 & perm[5,] != 0]
t1 = colSums(10^(3:0)*perm[1:4, ])
t2 = colSums(10^(3:0)*perm[c(5, 6, 7, 2), ])
t3 = colSums(10^(4:0)*perm[c(5, 6, 3, 2, 8), ])
return(perm[, perm[5, ] != 0 & t1+t2 == t3])
}
なお,e1071 にも,permutations があるが,こちらは速い。ただ,関数仕様が nPm ではなく nPn を計算するようになっているので,重複する結果の表示を許すか,さもなくば,最終結果を取り出すところがちょっと醜いプログラムになる。
f3 = function() {
library(e1071)
perm = t(e1071::permutations(10)[, 1:8])-1
perm = perm[,perm[1,] != 0 & perm[5, ] != 0]
t1 = colSums(10^(3:0)*perm[1:4, ])
t2 = colSums(10^(3:0)*perm[c(5, 6, 7, 2), ])
t3 = colSums(10^(4:0)*perm[c(5, 6, 3, 2, 8), ])
return(unique(t(perm[, perm[5, ] != 0 & t1+t2 == t3])))
}
f3 は f2 より 4 倍ほど速い。
おまけ
# DONALD + GERALD = ROBERT
f4 = function() {
library(e1071)
perm = t(e1071::permutations(10))-1
perm = perm[,perm[1,] != 0 & perm[5, ] != 0]
t1 = colSums(10^(5:0)*perm[c(1, 2, 3, 4, 5, 1), ])
t2 = colSums(10^(5:0)*perm[c(6, 7, 8, 4, 5, 1), ])
t3 = colSums(10^(5:0)*perm[c(8, 2, 9, 7, 8, 10), ])
ans = t1+t2 == t3
return(c(t1[ans], t2[ans], t3[ans]))
}
※コメント投稿者のブログIDはブログ作成者のみに通知されます