gpt4 book ai didi

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

转载 作者:数据小太阳 更新时间:2023-10-29 08:16:06 25 4
gpt4 key购买 nike

Ruby 可能不是这方面的最佳语言,但我很乐意在我的终端中使用它,所以这就是我要使用的语言。

我需要处理从 1 到 666666 的数字,所以我找出所有包含 6 但不包含 7、8 或 9 的数字。第一个数字将是 6 , 下一个 16 , 然后 26等等。然后我需要像这样打印 (6=6) (16=6) (26=6)当我有类似 60 的范围时至 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's excellent example

$,="\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)

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

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

  • gen numbers based on modulo 7 digits (so base-7 numbers)
  • 生成最后一个数字“smart”:这就是压缩范围的原因

那么……时间是什么时候?这是用 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 optimized version 我之前发帖:由于 OutOfMemory,我无法将 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​​;我在 2 小时前开始研究 ruby​​ koans...)

@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

关于ruby - Ruby 中的数字运算(需要优化),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5680725/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com