欧拉项目#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
是标准的索引,但您也可以将其用作数字。在这个例子中,你可以打电话给i
numbers_to_test
和x
successes
,这样你就不用费力去记住是什么了。
【参考方案1】:
首先,您的循环一直运行到i < 100
,而不是i < 1000
。
其次,将x[i] <- c(x, i)
替换为x <- 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 除非您可以证明,否则我认为您的条件还不够,因此我将回滚您的编辑。当然对于a
和 b
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 是的,这与您的答案相似。我只是从我在玩欧拉问题时发现的解决方案中复制它。我不想让你不高兴,但分享我的答案。当然,如果您愿意,我会删除我的答案。请告诉我。 不用担心。请注意,此解决方案要求a
和 b
互质。
@MatthewLundberg 感谢您指出这一点。我没有意识到这一点。所以,这不是一个通用解决方案。以上是关于欧拉项目#1 R的主要内容,如果未能解决你的问题,请参考以下文章