目前正在学习Ruby /编程的过程中,我遇到了这个问题:
你的任务是建造一座建筑物,它将是一堆n个立方体。底部的立方体的体积为
n^3
,上面的立方体的体积为(n-1)^3
,依此类推,直到顶部的体积为1^3
。 您将获得建筑物的总体积m
。获得m
后,您是否可以找到要构建的多维数据集n
的数量? 函数findNb(find_nb, find-nb)
的参数将是整数m
,如果n
存在,则必须返回整数n^3 + (n-1)^3 + ... + 1^3 = m
,例如n
或{{} 1}}如果没有这样的-1
。
这是我尝试解决这个问题:
n*
这似乎适用于我知道可以使用的输入,例如:
def find_nb(m)
(1..Float::INFINITY).each do |n|
if (1..n).inject(0) {|sum, value| sum + value**3} == m
return p n
else
next
end
end
end
我需要帮助的地区:
我不知道如果没有find_nb(4183059834009)
find_nb(135440716410000)
find_nb(40539911473216)
的值满足等式,我会如何理解它,因此输出n
作为输入,例如
-1
非常感谢任何有关如何改善现有代码的提示。
答案 0 :(得分:7)
提示1:你不需要去无穷大:在某个n
之后,总和将大于m
,并且会越来越远。
提示2:如果找到n
,由于return
,该函数将永远不会到达最后一行。
提示3:next
如果到达each
阻止的结尾,则会自动生成。
提示4:每次都不需要从头开始重新计算立方体的总和。你没有建造一座全新的建筑,只是在下方放置一个更大的立方体。
因此...
def find_nb(m)
n = 1
sum = 1
while sum < m
n += 1
sum += n**3
end
return sum == m ? n : -1
end
编辑:这是一个功能版本,但我认为上面的简单while
仍然更清晰(也可能更快):
def find_nb(m)
sum = 0
sizes = 1.upto(Float::INFINITY)
.lazy
.map { |n| sum += n ** 3 }
.take_while { |x| x <= m }
.to_a
sizes.last == m ? sizes.length : -1
end
答案 1 :(得分:1)
要修复代码,请在if-statement
中创建另一个分支,告诉您的迭代何时返回-1
。在next
迭代中不需要each
(归功于@Amadan指出这一点)。
注意,最好不要从方法定义中打印任何内容。调用方法时打印。压痕和间距得到改善。另请注意,我在变量total
中定义了多维数据集的总和:
def find_nb m
(1..Float::INFINITY).each do |n|
total = (1..n).inject(0) { |sum, value| sum + value**3 }
if total == m
return n
elsif total > m
return -1
end
end
end
find_nb 4183059834009 #=> 2022
find_nb 135440716410000 #=> 4824
find_nb 40539911473216 #=> 3568
find_nb 37 #=> -1
如果你想使用无限循环,Ruby有loop
。与with_index
一起使用,如下所示:
def find_nb m
loop.with_index(1) do |_,n|
t = (1..n).inject { |sum,i| sum + i**3 }
if t == m
return n
elsif t > m
return -1
end
end
end
find_nb 4183059834009 #=> 2022
find_nb 135440716410000 #=> 4824
find_nb 40539911473216 #=> 3568
find_nb 37 #=> -1