欧拉项目#1 R

Posted

技术标签:

【中文标题】欧拉项目#1 R【英文标题】:Euler Project #1 in R 【发布时间】:2014-03-08 08:55:54 【问题描述】:

问题

找出所有能被 3 或 5 整除的小于 1000 的数字的总和

我创建的一个解决方案:

x <- c(1:999)
values <- x[x %% 3 == 0 | x %% 5 == 0]
sum(values

第二个解决方案我无法上班,需要帮助。我已经把它贴在下面了。 我正在尝试使用循环(在这里,我使用 while(),然后我将尝试 for())。我仍在努力将索引(向量中的位置)的引用与向量中的值/观察值分开。循环似乎让我更难区分这两者。

为什么这不能产生 Euler #1 的答案?

x <- 0
i <- 1
while (i < 100) 
  if (i %% 3 == 0 | i %% 5 == 0) 
    x[i] <- c(x, i)
    
  i <- i + 1

sum(x)

用文字来说,这就是我所理解的正在发生的事情:

    x 的值为 0 i 得到值 1 虽然对象 i 的值(不是索引 #)是 如果能被 3 或 5 整除 将数字 i 添加到向量 x 按顺序将 1 添加到 i(以保持循环达到定义的 1e3 限制 对向量 x 中的所有项求和

我猜 x[i]

【问题讨论】:

解决保持索引和值分离问题的更通用方法是更具描述性的名称。尽管i 是标准的索引,但您也可以将其用作数字。在这个例子中,你可以打电话给inumbers_to_testxsuccesses,这样你就不用费力去记住是什么了。 【参考方案1】:

首先,您的循环一直运行到i &lt; 100,而不是i &lt; 1000

其次,将x[i] &lt;- c(x, i)替换为x &lt;- c(x, i),为向量添加一个元素。

【讨论】:

是的,感谢您了解这一点(100 对 1000)。好的,所以没有必要使用 [] 来表示我想将一个项目添加到向量中,对吗?通常我认为 x @jmo 你的理解是正确的。每次,您都将x 替换为一个新的(更长的)向量。 啊,它刚刚点击。谢谢!一段时间以来,我一直在面对各种练习题(我不会承认多久 :) 试图真正“得到它”。我现在知道了。谢谢!【参考方案2】:

这是我认为给出相同答案的替代方案(使用 99 而不是 999 作为上限):

iters <- 100
x <- rep(0, iters-1)
i <- 1

while (i < iters) 
  if (i %% 3 == 0 | i %% 5 == 0) 
    x[i] <- i
    
  i <- i + 1

sum(x)

# [1] 2318

这里是原帖中提到的for-loop

iters <- 99
x <- rep(0, iters)
i <- 1

for (i in 1:iters) 
  if (i %% 3 == 0 | i %% 5 == 0) 
    x[i] <- i
    
  i <- i + 1

sum(x)

# [1] 2318

【讨论】:

【参考方案3】:

还有一种方式:

x <- 1:999
sum(which(x%%5==0 | x%%3==0))
# [1] 233168

【讨论】:

【参考方案4】:

这是一个执行这个求和的捷径,这可能更符合问题的精神:

3*(333*334/2) + 5*(199*200/2) - 15*(66*67/2)
## [1] 233168

这就是为什么会这样:

在整数集合[1,999]中有:

333 个可被 3 整除的值。它们的总和为 3*sum(1:333)3*(333*334/2)

199 个可被 5 整除的值。它们的总和为 5*sum(1:199)5*(199*200/2)

将这些相加得到一个因它们的交集而过高的数字,即可以被 15 整除的值。有 66 个这样的值,它们的总和是 15*(1:66)15*(66*67/2)

作为 N 的函数,可以写成:

f <- function(N) 
  threes <- floor(N/3)
  fives  <- floor(N/5)
  fifteens <- floor(N/15)

  3*(threes*(threes+1)/2) +  5*(fives*(fives+1)/2) - 15*(fifteens*(fifteens+1)/2)

给予:

f(999)
## [1] 233168
f(99)
## [1] 2318

【讨论】:

这很整洁。我不确定,但我认为该函数甚至可以推广到任何两个除数,即使用 a、b 和 c 代替 3、5 和 15。 @MarkMiller 除非您可以证明,否则我认为您的条件还不够,因此我将回滚您的编辑。当然对于 ab prime 是有效的。 @MatthewLundberg 当 n = 20 时,我测试了 a 和 b 的大约 15 种组合的编辑,它总是给出正确的答案。我会将编辑放在我自己的帖子中。 @mark 尝试 10 和 14,限制为 1000。我想你会看到这是一个反例。而且我不同意您将我的内容作为您自己的答案,因为这与 Sven 所做的完全不同。但是,您可以使用自己的答案做您想做的事情。 @MatthewLundberg 我认为我从未听说过有人反对其他人推广开源代码。不过,如果您觉得这样做侵犯了您的内容,我不会打扰。我现在没有时间测试代码以确定素数之外存在哪些限制,但以后可能会这样做。【参考方案5】:

一个非常高效的方法如下:

div_sum <- function(x, n) 
  # calculates the double of the sum of all integers from 1 to n 
  # that are divisible by x
  max_num <- n %/% x
  (x * (max_num + 1) * max_num)      


n <- 999
a <- 3
b <- 5

(div_sum(a, n) + div_sum(b, n) - div_sum(a * b, n)) / 2

相比之下,一个非常的代码如下:

x=1:999
sum(x[!x%%3|!x%%5])

【讨论】:

@MatthewLundberg 是的,这与您的答案相似。我只是从我在玩欧拉问题时发现的解决方案中复制它。我不想让你不高兴,但分享我的答案。当然,如果您愿意,我会删除我的答案。请告诉我。 不用担心。请注意,此解决方案要求 ab 互质。 @MatthewLundberg 感谢您指出这一点。我没有意识到这一点。所以,这不是一个通用解决方案。

以上是关于欧拉项目#1 R的主要内容,如果未能解决你的问题,请参考以下文章

欧拉项目 | 243题 | 最简分数

sh 项目欧拉1

欧拉项目 | 329题 | 一只懂质数的青蛙

欧拉函数计算公式是啥?

欧拉项目010:2000000以内的素数和

欧拉公式的三种形式