使用R,计算x和y是整数∈[1,1000],存在多少个唯一幂,x ^ y。 这就是我现在所拥有的,只是不知道如何消除重复的数字,
x<-1:1000
y<-1:1000
for (i in x)
{
for (j in y){
print(i^j)
}
}
答案 0 :(得分:15)
这种组合方法可以将数字从1-1000分成等价类,其中类中的每个数字都是其他数字的幂。例如,我们将数字1-10分成(1),(2,4,8),(3,9),(5),(6),(7),(10)。等价类之间的值的幂都不会重合,所以我们可以分别处理每个等价类。
num.unique.comb <- function(limit) {
# Count number of powers in each equivalence class (labeled by lowest val)
num.powers <- rep(0, limit)
# Handle 1 as special case
num.powers[1] <- 1
# Beyond sqrt(limit), all unhandled numbers are in own equivalence class
handled <- c(T, rep(F, limit-1))
for (base in 2:ceiling(sqrt(limit))) {
if (!handled[base]) {
# Handle all the values in 1:limit that are powers of base
num.handle <- floor(log(limit, base))
handled[base^(1:num.handle)] <- T
# Compute the powers of base that we cover
num.powers[base] <- length(unique(as.vector(outer(1:num.handle, 1:limit))))
}
}
num.powers[!handled] <- limit
# Handle sums too big for standard numeric types
library(gmp)
print(sum(as.bigz(num.powers)))
}
num.unique.comb(10)
# [1] 76
num.unique.comb(1000)
# [1] 978318
这种组合方法的一个不错的特性是它与蛮力方法相比非常快。例如,在极限设置为1000的情况下计算时间不到0.1秒。这使我们可以计算更大值的结果:
# ~0.15 seconds
num.unique.comb(10000)
# [1] 99357483
# ~4 seconds
num.unique.comb(100000)
# [1] 9981335940
# ~220 seconds
num.unique.comb(1000000)
# [1] 999439867182
这是一个非常简洁的结果 - 在4分钟内,我们可以计算1万亿个数字内的唯一值数量,其中每个数字最多可以有600万个数字!
更新:根据此组合代码,我已更新OEIS entry for this sequence以包含最多10,000个字词。
答案 1 :(得分:7)
蛮力方法是计算所有权力并计算唯一值的数量:
num.unique.bf <- function(limit) {
length(unique(as.vector(sapply(1:limit, function(x) x^(1:limit)))))
}
num.unique.bf(10)
# [1] 76
这种强力分析的一个问题是你正在处理会产生数值问题的大数字。例如:
1000^1000
# [1] Inf
结果我们得到一个不准确的值:
# Wrong due to numerical issues!
num.unique.bf(1000)
# [1] 119117
然而,像gmp
这样的软件包可以让我们计算甚至大到1000 ^ 1000的数字。我的计算机一次将所有100万个数字存储在内存中,因此我将它们写入文件(n = 1000的大小在我的计算机上为1.2 GB),然后计算该文件中唯一值的数量:
library(gmp)
num.unique.bf2 <- function(limit) {
sink("foo.txt")
for (x in 1:limit) {
vals <- as.bigz(x)^(1:limit)
for (idx in 1:limit) {
cat(paste0(as.character(vals[idx]), "\n"))
}
}
sink()
as.numeric(system("sort foo.txt | uniq | wc -l", intern=T))
}
num.unique.bf2(10)
# [1] 76
num.unique.bf2(1000)
# [1] 978318
快速访问OEIS(单击前1000个值的链接)表明这是正确的。这种方法相当慢(在我的计算机上大约40分钟),组合方法应该明显更快。