Ruby中的数字运算(需要优化)
|
Ruby可能不是最佳的语言,但是我很愿意在终端中使用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) }
正如我说的那样,它甚至可以用于数以百万计的数字-但是我想就如何使自己更漂亮,更高效提供一些建议。
没有找到相关结果
已邀请:
10 个回复
逆捐凶撤小
与x3ro的版本相比 ...下降到三行 ...更快204.2倍(至66666666) ...具有字节相同的输出 它使用了我所有的想法进行优化 gen数字基于模7位数(所以以7为底的数字) 生成最后一位数字“'smart \':这是压缩范围的原因 那么...几点钟?这是用8位数字进行测试(到66666666或823544行输出):
即使性能确实不错,但它甚至与我之前发布的C优化版本也不接近:由于OutOfMemory,我无法将my.rb运行到6666666666(6x10)。当运行到9位数字时,这是比较结果:
C版本仍然快了15倍...考虑到它在裸机上运行,这才算公平。 希望您喜欢它,如果仅出于学习Ruby的目的,请允许我投票:) (你能告诉我我很自豪吗?这是我第一次与红宝石相遇; 2个小时前,我开始了红宝石可汗...) 由@johndouthat编辑: 非常好! base7的用法非常聪明,这对于您的第一次红宝石试用来说是一件很棒的事情:) 这是对代码段的略微修改,可让您测试10位以上的数字而不会出现OutOfMemory错误:
锹缄
打印出以下内容:
等等...
盟犯涩沟都
)的所有数字,并以7为基数的打印方式,那么您将至少丢弃所有包含7,8,9的数字。这包括MrE的优化建议,除了将问题提升为简单的整型算术而不是字符序列处理。 剩下的就是检查是否至少有6个项目。这将使算法连续最多跳过6个项目,因此我认为它的重要性降低了(总范围内可跳过项目的平均数量为40% )。 简单基准达到6666666666 (请注意,这意味着输出6位数的222,009,073(222M)行) 紧贴这个想法,我编写了这个经过高度优化的C代码(我不会说ruby)来演示这个想法。我将其运行到282475248(与6666666666(mod 7)一致),因此它更像是一个衡量基准:0m26.5s
我还对另一种方法进行了基准测试,毫不奇怪的是,该方法运行时间不到一半,因为 此版本直接以ascii字符串形式处理结果,准备显示 此版本将
标志快捷方式缩短了递归级别 当要求为\'6 \'时,此版本还会优化最后一位的'twiddling' 该代码只是更短... 播放时间:0m12.8s
基准测试:
镀建啼
凰葱崎济邯
荆怖赡
以及使用方法:
稍惮
,您知道可以安全地跳过至少
...
骂陋冠
代替
我让OP决定,这是修改后的版本,它的运行时间是x3ro版本的18%(生成6666666(7x6)时为3.2s而不是17.0s)。
览幕堤分
疏腔傻小雹
范围支持迭代,因此遍历整个范围并累积将您的细分包括在块中的数字会更好。当一个块完成并被另一个替换时,您可以将其写出。