草庐IT

ruby - 从列表中生成从 n 到 m 的数字

coder 2025-07-06 原文

我将从一个例子开始;给定 n = 1 和 m = 100 以及一个列表 [1, 2, 3] 生成所有包含一位数和两位数的数字等等,但在这种情况下它们需要小于 100。

输出:

- 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33

然后我们停止,因为下一个数字将超过 100,例如:

- 111, 112, 113, 121, 122, 123, 131, 132, 133, 21..,. 22..., 23..., 31, 32, 33

正如您所注意到的,我将 1, 2, 3, 4 附加到之前创建的数字,为此我使用了一个递归函数,该函数在 for 循环中为我的列表,它们会一直运行,直到生成的数字大于我的限制。

def x(str, finish, d, c) 
  return if d >= finish
  [1, 2, 3, 4].each do |e|
    x(str, end, d*c+e)
  end

  # do something if d >= str
end

如果我需要从 1 开始,这很好用,但如果我的起始数字大很多,我仍然需要开始创建这个序列。

有人可以帮我提供一个可以产生相同序列的解决方案,但是从任何起点而不是 1 开始,所以如果例如起点是 100 并且结束点是 200,则输出将是:

111、112、113、114、121、122、123、124、131、132、132 [...]

任何编程语言的解决方案都很好,但请不要内置核心库。

最佳答案

代码

def generate_em(minimum, maximum, list)
  digits_min = minimum.to_s.size
  digits_min += 1 if minimum > (list.max.to_s*digits_min).to_i
  digits_max = maximum.to_s.size
  digits_max -= 1 if maximum < (list.min.to_s*digits_max).to_i
  (digits_min..digits_max).each_with_object([]) { |n,arr|
    arr.concat(list.repeated_permutation(n).to_a.map { |a| a.join.to_i }) }.
      uniq.
      select { |n| (minimum..maximum).cover?(n) }
end

示例

#1

minimum =   1
maximum = 100
list = [1, 2, 3]

generate_em(minimum, maximum, list)
  #=> [1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33] 

#2

minimum = 78
maximum = 3332
list = [3, 4, 5, 6, 7]

generate_em(minimum, maximum, list)
  #=> [333, 334, 335, 336, 337, 343, 344, 345, 346, 347, 353, 354, 355, 356,
  #    357, 363, 364, 365, 366, 367, 373, 374, 375, 376, 377, 433, 434, 435,
  #    436, 437, 443, 444, 445, 446, 447, 453, 454, 455, 456, 457, 463, 464,
  #    465, 466, 467, 473, 474, 475, 476, 477, 533, 534, 535, 536, 537, 543,
  #    544, 545, 546, 547, 553, 554, 555, 556, 557, 563, 564, 565, 566, 567,
  #    573, 574, 575, 576, 577, 633, 634, 635, 636, 637, 643, 644, 645, 646,
  #    647, 653, 654, 655, 656, 657, 663, 664, 665, 666, 667, 673, 674, 675,
  #    676, 677, 733, 734, 735, 736, 737, 743, 744, 745, 746, 747, 753, 754,
  #    755, 756, 757, 763, 764, 765, 766, 767, 773, 774, 775, 776, 777] 

#3

minimum = 0
maximum = 100
list = [0, 1, 2]

generate_em(minimum, maximum, list)
  #=> [0, 1, 2, 10, 11, 12, 20, 21, 22, 100]

解释

示例 #1

上面第一个例子的步骤如下。

digits_min = minimum.to_s.size
  #=> 1 

如果 mimum 大于 list 中最大的 digits_min 位数,则将 digits_min 增加一。

digits_min += 1 if minimum > (list.max.to_s*digits_min).to_i
digits_min
  #=> 1 

digits_max = maximum.to_s.size
  #=> 3 

如果 maximum 小于 list 中最小的 digits_max 数字,则将 digits_max 减一。

digits_max -= 1 if maximum < (list.min.to_s*digits_max).to_i
digits_max
  #=> 2

我们通过将 digits_max3 减少到 2 来提高效率

c = digits_min..digits_max
  #=> 1..2 
d = c.each_with_object([])
  #=> #<Enumerator: 1..2:each_with_object([])> 

我们可以通过调用 Enumerable#entries (或 Enumerable#to_a )来查看此枚举器将生成​​的元素。

d.entries
  #=> [[1, []], [2, []]]

n, arr = d.next
  #=> [1, []] 
n #=> 1 
arr
  #=> [] 
e = list.permutation(n)
  #=> #<Enumerator: [1, 2, 3]:permutation(2)>
f = e.to_a
  #=> [[1], [2], [3]] 
arr.concat f
  #=> [[1], [2], [3]] 
n, arr = d.next
  #=> [2, [[1], [2], [3]]] 
n #=> 2 
arr
  #=> [[1], [2], [3]] 
e = list.permutation(n)
  #=> #<Enumerator: [1, 2, 3]:permutation(2)> 
f = e.to_a
  #=> [[1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]] 
arr.concat f
  #=> [[1], [2], [3], [1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2]] 

arreach_with_object 的 block 返回。

g = arr.map { |a| a.join.to_i }
  #=> [1, 2, 3, 12, 13, 21, 23, 31, 32]
h = g.uniq
  #=> [1, 2, 3, 12, 13, 21, 23, 31, 32]
h.select { |n| (minimum..maximum).cover?(n) }
  #=> [1, 2, 3, 12, 13, 21, 23, 31, 32]

示例 #2

在第二个示例中,没有生成两位数组合,因为

78 > (list.max.to_s*2).to_i
  #=> 78 > 77 => true

并且没有生成四位数组合,因为

3332 < (list.min.to_s*4).to_i
  #=> 3332 < 3333 => true 

示例 #3

如果没有 uniq,该方法将返回重复值:

[0, 1, 2, 0, 1, 2, 10, 11, 12, 20, 21, 22, 0, 1, 2, 10, 11, 12, 20, 21, 22, 100]

关于ruby - 从列表中生成从 n 到 m 的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42461971/

有关ruby - 从列表中生成从 n 到 m 的数字的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  4. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  5. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  6. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  7. ruby-on-rails - rails : keeping DRY with ActiveRecord models that share similar complex attributes - 2

    这似乎应该有一个直截了当的答案,但在Google上花了很多时间,所以我找不到它。这可能是缺少正确关键字的情况。在我的RoR应用程序中,我有几个模型共享一种特定类型的字符串属性,该属性具有特殊验证和其他功能。我能想到的最接近的类似示例是表示URL的字符串。这会导致模型中出现大量重复(甚至单元测试中会出现更多重复),但我不确定如何让它更DRY。我能想到几个可能的方向...按照“validates_url_format_of”插件,但这只会让验证干给这个特殊的字符串它自己的模型,但这看起来很像重溶液为这个特殊的字符串创建一个ruby​​类,但是我如何得到ActiveRecord关联这个类模型

  8. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  9. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  10. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

随机推荐