Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 将数字分成相等的部分或什么';这是最接近的_Ruby On Rails_Ruby_Math - Fatal编程技术网

Ruby on rails 将数字分成相等的部分或什么';这是最接近的

Ruby on rails 将数字分成相等的部分或什么';这是最接近的,ruby-on-rails,ruby,math,Ruby On Rails,Ruby,Math,我有一个随机数,我想把它分成几个部分(加数),条件是一个部分不能超过20,并且各部分之间必须尽可能接近 例如,如果我的随机数是41,那么加数应该是14,14,13。 若随机数为60,则加数应为20,20,20。 若随机数为21,则加数应为11和10 等等 我的代码是用Ruby(Rails)编写的,因此我非常希望能给出一个答案,用Ruby高效地实现这个问题,尽管也欢迎使用伪代码或其他编程语言 这是我在数组中发现的,但我确实需要对数字执行此操作:“没有内置函数来执行此操作 我可以为您写出解决方案,但

我有一个随机数,我想把它分成几个部分(加数),条件是一个部分不能超过20,并且各部分之间必须尽可能接近

例如,如果我的随机数是41,那么加数应该是14,14,13。 若随机数为60,则加数应为20,20,20。 若随机数为21,则加数应为11和10 等等

我的代码是用Ruby(Rails)编写的,因此我非常希望能给出一个答案,用Ruby高效地实现这个问题,尽管也欢迎使用伪代码或其他编程语言


这是我在数组中发现的,但我确实需要对数字执行此操作:“

没有内置函数来执行此操作

我可以为您写出解决方案,但一般来说,您应该在StackOverflow问题中包含您自己的尝试。这类问题似乎是学习ruby语言基础的练习。如果你不确定从哪里开始,我建议你读一本Ruby教科书

def split_number_into_three(number) # i.e. number=32
  base = Array.new(3, (number / 3)) # i.e. base=[10,10,10]
  remainder = number % 3            # i.e. remainer=2
  return base if remainder.zero?
  while remainder > 0
    base.each_with_index do |num, idx|
      if remainder > 0
        base[idx] += 1
        remainder -= 1
      end
    end
  end
  base
end
运行此代码:

irb(main):035:0> split_number_into_three(32)
=> [11, 11, 10]

你可以用这个很酷的单衬里。它应该可以除以你想要的任何数量的碎片:

def split_into n, p
    [n/p + 1] * (n%p) + [n/p] * (p - n%p)
end

print (split_into 32, 3) # => [11, 11, 10]
它基本上将数字分成相等的部分,并将余数除以第一部分(每个部分1)。事实上,你可以将数组相乘和相加,就像这样:

[1] * 3     # => [1, 1, 1]
[1] + [2]   # => [1, 2]
编辑:考虑到每件作品应小于20件的规则,您可以按照@Cary Swoveland的建议计算出理想的作品数量:

p = (n / 20.0).ceil
代码

n
为要除以的给定数字,
m
为每个分量的最大值

def doit(n,m)
  nbr_components = (n/(m.to_f)).ceil
  smaller, nbr_larger = n.divmod(nbr_components)
  { smaller=>nbr_components-nbr_larger, smaller+1=>nbr_larger }.
    delete_if { |_,v| v.zero? }
end
是一种经常被忽视的方法,有很多用途

示例

(1..300).to_a.sample(15).sort.each { |n| puts "doit(#{n},20) = #{doit(n,20)}" }
doit(2,20)   = {2=>1}
doit(7,20)   = {7=>1}
doit(13,20)  = {13=>1}
doit(19,20)  = {19=>1}
doit(32,20)  = {16=>2}
doit(36,20)  = {18=>2}
doit(47,20)  = {15=>1, 16=>2}
doit(61,20)  = {15=>3, 16=>1}
doit(77,20)  = {19=>3, 20=>1}
doit(146,20) = {18=>6, 19=>2}
doit(149,20) = {18=>3, 19=>5}
doit(160,20) = {20=>8}
doit(199,20) = {19=>1, 20=>9}
doit(253,20) = {19=>7, 20=>6}
doit(275,20) = {19=>5, 20=>9}

doit(11_347_155, 20)
  #=> {19=>5, 20=>567353}
5*19 + 567353*20
  #=> 11347155
解释

假设:

n = 77
m = 20
步骤如下:

nbr_components = (n/(m.to_f)).ceil
  #=> (77/20.0).ceil
  #=> 3.85.ceil
  #=> 4 
smaller, nbr_larger = n.divmod(nbr_components)
  #=> 77.divmod(4) 
  #=> [19, 1] 
smaller
  #=> 19
nbr_larger
  #=> 1
h = { smaller=>nbr_components-nbr_larger, smaller+1=>nbr_larger }
  #=> {19=>3, 20=>1}
h.delete_if { |_,v| v.zero? }
  #=> {19=>3, 20=>1}

欢迎来到SO。请阅读“”,包括该页中的链接。你要我们为你写代码?这不是堆栈溢出的目的。相反,你做研究,你尝试,然后,当你遇到问题,你告诉我们你尝试了什么,我们帮助你解决它。有助于阅读。你希望有多少个加数?那么这就离题了:“要求我们推荐或查找书籍、工具、软件库、教程或其他非网站资源的问题,因为它们往往会吸引自以为是的答案和垃圾邮件,所以离题了。相反,到目前为止,我们已经做了哪些工作来解决它。”现在看起来你只看了一页。还有什么地方?@theTinMan你知道我在你编辑评论之前看到了你的评论,对吗?你的态度有严重问题,我的朋友,我希望有一天你会好起来。同时,请看这个问题,它有你提到的类似问题,我认为这是你让世界变得更美好的机会:你最后的评论是非常不恰当的@多年来,theTinMan为Ruby社区做出了巨大贡献,我记得,他是第三高的代表。他只是告诉你关于SO的政策,你的反应是告诉他,他的态度不好,他可以如何更有效地利用时间。随着您在SO上花费更多的时间,您将看到tTM会留下许多类似的评论,以努力提高SO上发布的问题的质量。没有理由因为你不想做而粗鲁。太好了,太棒了,谢谢你。我实现了这个方法,效果非常好。当然,我们可以很容易地修改它,将其称为split_number_into_n,以控制我希望我的号码被分割成的部分的数量。尽管如此,斯莱舍尔茨的回答似乎更接近于我所问的,所以我对此投了赞成票,并接受了Mizunix,这显然不可能是真的,因为该方法没有考虑最大允许值(即20)。注意:
split_为1_000_000,1)#=>[1000000]
@mizunix是的,我理解你为什么选择“酷一行”。他们不可能都是赢家@CarySwoveland你的问题是对的。虽然我相信这个答案很接近。它只需要一个小的加法,即在方法中移动'p'并将其设置为1。然后把它放入一个循环中,然后
p+=1
直到
n/p<21
@caryswovel,这就是我们所说的答案,对吗?使用我的循环
将_拆分为1_000_000,1)#=>[1000000]
不是真的。由于1000000/1>20,它将尝试1000000/2,然后1000000/3,依此类推,直到它达到返回数字为20或更少的值。在这之后,Sly的代码就像需要完成的charmThen一样工作。无需迭代:
p=(n/20.0).ceil