Ruby 中的数字运算(需要优化)

2024-05-04

Ruby 可能不是最适合这种情况的语言,但我很乐意在我的终端中使用它,所以这就是我要使用的。

我需要处理从 1 到 666666 的数字,因此我找出包含 6 但不包含 7、8 或 9 的所有数字。第一个数字是6, 下一个16, then 26等等。 然后我需要像这样打印(6=6) (16=6) (26=6)当我有这样的范围时60 to 66我需要像这样打印(60 THRU 66=6)(SPSS 语法)。

我有这段代码并且它可以工作,但它既不美观也不高效,那么我该如何优化它呢?

(可能会出现愚蠢的代码)

class Array
  def to_ranges
    array = self.compact.uniq.sort
    ranges = []
    if !array.empty?
      # Initialize the left and right endpoints of the range
      left, right = array.first, nil
      array.each do |obj|
        # If the right endpoint is set and obj is not equal to right's successor 
        # then we need to create a range.
        if right && obj != right.succ
          ranges << Range.new(left,right)
          left = obj
        end
        right = obj
      end
      ranges << Range.new(left,right) unless left == right
    end
    ranges
  end
end

write = ""
numbers = (1..666666).to_a

# split each number in an array containing it's ciphers
numbers = numbers.map { |i| i.to_s.split(//) }

# delete the arrays that doesn't contain 6 and the ones that contains 6 but also 8, 7 and 9
numbers = numbers.delete_if { |i| !i.include?('6') }
numbers = numbers.delete_if { |i| i.include?('7') }
numbers = numbers.delete_if { |i| i.include?('8') }
numbers = numbers.delete_if { |i| i.include?('9') }

# join the ciphers back into the original numbers
numbers = numbers.map { |i| i.join }

numbers = numbers.map { |i| i = Integer(i) }

# rangify consecutive numbers
numbers = numbers.to_ranges

# edit the ranges that go from 1..1 into just 1
numbers = numbers.map do |i|
  if i.first == i.last
    i = i.first
  else
    i = i
  end
end

# string stuff
numbers = numbers.map { |i| i.to_s.gsub(".."," thru ") }

numbers = numbers.map { |i| "(" + i.to_s + "=6)"}

numbers.each { |i| write << " " + i }

File.open('numbers.txt','w') { |f| f.write(write) }

正如我所说,它适用于甚至数百万的数字 - 但我想要一些关于如何变得更漂亮和更高效的建议。


我删除了之前的尝试parlez-vous-ruby?并弥补了这一点。我知道有一个优化版本x3ro的优秀例子.

$,="\n"
puts ["(0=6)", "(6=6)", *(1.."66666".to_i(7)).collect {|i| i.to_s 7}.collect do |s|
    s.include?('6')? "(#{s}0 THRU #{s}6=6)" : "(#{s}6=6)"
end ]

与x3ro版本相比

...减少到三行

... 速度提高 204.2 倍(达到 66666666)

...具有字节相同的输出

它使用了我所有的优化想法

  • 基于模 7 数字的 gen 数字(因此基数为 7 的数字)
  • 生成最后一个数字“智能”:这就是压缩范围的原因

那么...时间安排是怎样的?这是使用 8 位数字进行测试(达到 66666666 或 823544 行输出):

$ time ./x3ro.rb >  /dev/null

real    8m37.749s
user    8m36.700s
sys 0m0.976s

$ time ./my.rb >  /dev/null

real    0m2.535s
user    0m2.460s
sys 0m0.072s

虽然演技确实不错,但是甚至不接近C优化版本 https://stackoverflow.com/questions/5680725/number-crunching-in-ruby-optimisation-needed/5682791#5682791我之前发布过:我无法将 my.rb 运行到 6666666666 (6x10) 因为内存不足。当运行到9位数时,这是比较结果:

sehe@meerkat:/tmp$ time ./my.rb >  /dev/null

real    0m21.764s
user    0m21.289s
sys 0m0.476s

sehe@meerkat:/tmp$ time ./t2 > /dev/null

real    0m1.424s
user    0m1.408s
sys 0m0.012s

C 版本仍然快了 15 倍……考虑到它在裸机上运行,​​这是公平的。

希望你喜欢它,如果只是为了学习 Ruby,我可以请你投票吗:)

(你能说我很自豪吗?这是我第一次接触Ruby;我两小时前开始了红宝石公案......)

编辑@johndouthat:

很不错! Base7 的使用非常巧妙,这对于您的第一次 Ruby 试用来说是一个很棒的工作:)

以下是对代码片段的轻微修改,可以让您测试 10 多个数字而不会出现 OutOfMemory 错误:

puts ["(0=6)", "(6=6)"]
(1.."66666666".to_i(7)).each do |i| 
  s = i.to_s(7)
  puts s.include?('6') ? "(#{s}0 THRU #{s}6=6)" : "(#{s}6=6)"
end

# before:
real    0m26.714s
user    0m23.368s
sys 0m2.865s
# after
real    0m15.894s
user    0m13.258s
sys 0m1.724s
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ruby 中的数字运算(需要优化) 的相关文章

随机推荐

  • ElasticSearch 多滚动 Java API

    我想从索引中获取所有数据 由于项目数量对于内存来说太大 我使用滚动 很好的功能 client prepareSearch index setTypes myType setSearchType SearchType SCAN setScro
  • 在 LINQ 中选择案例[重复]

    这个问题在这里已经有答案了 我怎样才能把它翻译成 LINQ 呢 select t age as AgeRange count as Users from select case when age between 0 and 9 then 0
  • Gson解析没有键值对的字符串

    我正在尝试使用 Gson 库解析字符串 但没有成功 这是我的字符串 1 816513 52 5487566 1 8164913 52 548824 此示例中的问题是没有键值对 我查看了其他示例 但它们都有键值对 看起来不像我的问题 我的解决
  • 从 R Markdown 中的字数统计中排除部分

    我正在用 Rmarkdown 写一篇论文 通过 LaTeX 导出为 PDF 我需要计算正文中的字数 对于 LaTeX 文档 我使用texcount从命令行 使用我的 tex 文档中的以下标签指定要从字数统计中排除的部分 TC ignore
  • 通过排队预加载图像?

    我正在寻找一种预加载特定图像并将其添加到队列中的方法 这是我目前所处的位置 http shivimpanim org testsite imageloader html http shivimpanim org testsite image
  • 使用PathModifier或MoveYModifier来模拟精灵跳跃

    我在 AndEngine 中使用这个方法来确定用户触摸的场景 Override public boolean onSceneTouchEvent Scene pScene TouchEvent pSceneTouchEvent if pSc
  • 如何调试 MySQL 上的锁等待超时?

    在我的生产错误日志中 我偶尔会看到 SQLSTATE HY000 一般错误 1205 超过锁等待超时 尝试 重新开始交易 我知道当时哪个查询正在尝试访问数据库 但是有没有办法找出哪个查询在那个精确时刻拥有锁定 暴露这一点的是这个词交易 从该
  • BERT 输出不确定

    BERT 输出是不确定的 当我输入相同的输入时 我希望输出值是确定性的 但我的 bert 模型的值正在变化 听起来很尴尬 同一个值返回两次 一次 也就是说 一旦出现另一个值 就会出现相同的值并重复 如何使输出具有确定性 让我展示我的代码片段
  • MassTransit 生成我想忽略的_skipped 队列

    任何人都可以猜出问题是什么 因为我不知道如何解决这个问题 大众运输产生 skipped队列 我不知道为什么它会生成这些队列 它是在执行发布请求响应时生成的 请求客户端是使用 MassTransit RequestClientExtensio
  • 当包含非 ASCII 字符时,无法使用 lambda S3 事件给出的密钥

    我有一个 Python lambda 脚本 可以在图像上传到 S3 时缩小图像 当上传的文件名包含非 ASCII 字符 在我的例子中是希伯来语 时 我无法获取该对象 禁止 就好像该文件不存在一样 这是我的 一些 代码 s3 client b
  • Maven - 在构建时包含不同的文件

    我有十个 WAR 文件 所有这些文件都有几乎相同的代码和标记 唯一的区别在于图像 CSS 和消息 我偶然发现了配置文件的概念 但我还没有完全理解它 我不确定这是否可以处理我需要它做的事情 基本上 我想要一个针对 10 个不同 WAR 具有不
  • 在 Transact SQL 中何时使用 EXCEPT 而不是 NOT EXISTS?

    我最近刚刚通过阅读同事编写的代码了解到 SQL Server 中存在新的 EXCEPT 子句 有点晚了 我知道 真的让我很惊讶 但是我对它的使用有一些疑问 建议什么时候使用它 使用它与使用 AND NOT EXISTS 的相关查询在性能方面
  • JavaFX 中 ImageView 的顺序转换

    我已经看过了如何在 javafx 2 1 中等待转换结束 https stackoverflow com questions 11188018 how to wait for a transition to end in javafx 2
  • Fabric JS html 5 图像弯曲选项

    我想用html5工具制作图像曲线 我使用 Fabric js 作为 html5 画布工具 请指导我如何在杯子 玻璃 圆柱形或圆形产品等图像上制作弯曲图像 参考号图片如下 http vsdemo cwwws com Images Produc
  • 错误:在函数返回类型中推导类类型“元组”

    我在做什么 三年后我开始练习c 我需要快速 广泛地学习 所以我试图解决的这个例子对你来说可能看起来很奇怪 我在用c 20 gcc 10 2 我想做一个python 枚举函数 that 采取任何container
  • Groovy 有“use strict”吗?

    我记得从我的 Perl 时代起 使用严格 http perldoc perl org strict html 导致运行时执行额外验证的语句 Groovy 是否有等效的语句 我不喜欢在运行时被编译时检测到的东西所困扰 比如向构造函数传递的参数
  • 使用 C# 创建 SQL Server 备份文件 (.bak) 到任何位置

    我正在尝试用 C 编写简单的应用程序 它允许我备份 压缩并通过 ftp 发送我的 SQL Server 数据库 我遇到的一个问题是 如果我尝试在 C Program Files Microsoft SQL Server MSSQL 3 MS
  • 使用Python Selenium访问网页上的表对象

    一段时间以来 我尝试从网页中提取下表 我正在尝试进入网站上不同页面的 tr 对象 1 8 我设法存储并打开页面 并希望循环遍历表 tbody 其中包含 tr 对象 表示我想要访问的信息行 然而 当运行以下代码时 我只获得所有 8 个页面中的
  • Angular 模板调用函数可以返回 Promise

    Angular 的 q 文档 http docs angularjs org api ng 24q说 q 承诺被模板引擎以角度方式识别 这意味着在模板中 您可以将附加到范围的承诺视为结果值 Angular 的视图模板还允许您计算表达式 这意
  • Ruby 中的数字运算(需要优化)

    Ruby 可能不是最适合这种情况的语言 但我很乐意在我的终端中使用它 所以这就是我要使用的 我需要处理从 1 到 666666 的数字 因此我找出包含 6 但不包含 7 8 或 9 的所有数字 第一个数字是6 下一个16 then 26等等