0 0

Ruby算法求优化:spoj PRIME150

原问题见 https://www.spoj.pl/problems/PRIME1/
打印m到n内所有质数,每行一个

要求:用Ruby写,对于m=999900000, n=1000000000,比下面这个程序快一倍就行了

$stdin=DATA
require 'benchmark'
elapsed = Benchmark.measure do

# Begin of program--------------------

#使用双筛法:先用普通筛法产生sqrt(n)以内的质数表,然后按质数表筛m, n内的整数
(t = gets.to_i).times do |c|
  m,n = gets.split(' ').map{|e|e.to_i}

  #ps:sqrt(n)以内质数表
  pmax = Math.sqrt(n).to_i 
  ps = []
  3.step pmax, 2 do |i|
    ps << i
  end

  #一筛
  imax = Math.sqrt(pmax).to_i + 1
  3.step imax, 2 do |i|
    ps.delete_if do |e|
      e % i == 0 && e != i
    end
  end

  #准备数组:填入m到n内的一堆奇数
  if m <= 2
    puts 2
    m = 3
  end
  m += 1 if m%2 == 0
  res = []
  m.step n, 2 do |e|
    res << e
  end

  #二筛
  if m <= pmax  #m比较小时,ps可能包含m,所以加一个!=
    for p in ps
      res.delete_if do |e| 
        e % p == 0 && e != p
      end
    end
  else #m比较大时,不用判断 e!=p,稍微减少负担。
    align = 16
    while (sz = ps.size) % align > 0
      ps[sz] = ps[sz-1]
    end
    #重头戏在下面,这个瓶颈能解决,世界就和谐了!
    #这里使用切片大小为16的each_slice,比each快约50%
    #数组方括号方法极其缓慢!写成这样实在是不得已
    ps.each_slice align do |p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16|
      #reject!直接调用 rb_arr_reject_bang() 进行迭代
      res.reject! do |e|
        e % p1 == 0 or
        e % p2 == 0 or
        e % p3 == 0 or
        e % p4 == 0 or
        e % p5 == 0 or
        e % p6 == 0 or
        e % p7 == 0 or
        e % p8 == 0 or
        e % p9 == 0 or
        e % p10 == 0 or
        e % p11 == 0 or
        e % p12 == 0 or
        e % p13 == 0 or
        e % p14 == 0 or
        e % p15 == 0 or
        e % p16 == 0
      end
    end
  end

  #输出结果
  puts res
  puts "\n" if not c==t-1
end

# End of program ----------------

end
puts elapsed #看看多长时间能跑完

#__END__后是输入数据,第一行表示输入的数据的组数,后面每行格式为:m n
__END__
2
999900000 1000000000
1 10


难点在于:Ruby很慢,同样的算法在C里面零点几秒就能完成了。
ruby的mathn库完全就是业余人士作品,Prime类比单筛法还要慢……

我还尝试过费马小定理的“逆定理”(但是还要剔除伪素数)等方法,
但是Ruby产生新对象代价极其高昂,a^n mod n这种运算也很杀性能。

各位有闲人士,帮个忙吧~
问题补充:
fivestarwy 写道
试试素数测试

Rabin-Miller方法也要调用模幂运算,分解开来就会多次创建对象
问题补充:
引用
你可以用c++写成dll,然后ruby调用!

人家是online judge,服务器运行,连调用File都不允许……
问题补充:
引用
你能不能把你写的算法和那几种方法来对比一下时间,给我们看看!

这可是50分题耶
2009年3月09日 23:03

7个答案 按时间排序 按投票排序

0 0

据说1.9.1的mathn.rb的each循环要好些!

2009年3月19日 18:50
0 0

你用ruby1.9.1的mathn覆盖掉你现在的mathn,试试了!

2009年3月19日 17:56
0 0

我的意思是你把Prime和你的算法,用的时间列举一下,让我们也感性认识一下。

2009年3月17日 08:11
0 0

你能不能把你写的算法和那几种方法来对比一下时间,给我们看看!

2009年3月16日 22:35
0 0

你可以用c++写成dll,然后ruby调用!

2009年3月16日 21:47
0 0

就我所知,素数测试速度是最快了的,要不就只有打表打多一点

PS:我不懂ruby

2009年3月11日 16:10
0 0

试试素数测试

2009年3月11日 15:31

相关推荐

    SPOJ-Solutions:SPOJ算法问题的解决方案

    SPOJ(Sphere Online Judge)是一个在线编程竞赛平台,它提供了大量的算法问题供程序员解决,以提高他们的编程技能和算法理解。"SPOJ Solutions"是这个领域的一个资源集合,包含了解决SPOJ上各种问题的代码示例,...

    SPOJ.rar_SPOJ

    这个名为"SPOJ.rar_SPOJ"的压缩包文件,很可能包含了越南版SPOJ(VN.SPOJ)上的问题解决方案,帮助用户提升编程技能和算法理解。 在SPOJ平台上,用户可以遇到各种难度级别的算法问题,从基础的数据结构和算法到复杂...

    WYMIANA---Zamiana-miejsc:SPOJ

    1. **理解问题**:首先,我们需要去Spoj网站上查找这个题目,或者从其他来源获取详细的描述和输入输出规范,以便了解问题的具体要求。 2. **数据结构**:考虑到涉及到元素的交换,数组(如`std::vector`)或动态...

    SPOJ-Solutions:SPOJ 问题的解决方案

    SPOJ(Sphere Online Judge)是一个在线编程竞赛平台,它提供了大量的算法问题供程序员解决,以提高他们的编程技能和算法理解。在这个名为"SPOJ Solutions"的资源中,你将找到针对SPOJ上问题的解决方案,主要使用...

    SPOJ-2.zip_SPOJ_SPOJ-TRIKA.cpp_online judge_sPOJ-Solution_spoj2

    1. **在线判题系统**:SPOJ作为一个在线判题平台,其核心功能在于接收用户的程序输入,对输入数据进行处理,然后与预期结果进行对比,判断程序是否正确解决了问题。这对于测试和优化代码的效率、准确性具有重要作用...

    cp:一些SPOJ问题的解决方案

    标题 "cp:一些SPOJ问题的解决方案" 暗示了这是一个关于计算机编程,特别是针对SPOJ(Sphere Online Judge)平台上的算法问题解决的资源。SPOJ是一个在线的编程竞赛平台,用户可以在这里提交代码来解决各种算法问题,...

    SPOJ:Python中SPOJ问题的解决方案

    在编程竞赛领域,SPOJ(Sphere Online Judge)是一个广受欢迎的在线判题系统,它提供了大量的编程题目供参赛者解决,以提升算法和编程能力。对于Python爱好者来说,掌握如何在SPOJ上高效地解决问题是至关重要的。...

    spoj:Haskell 中的 Spoj 算法

    通过阅读源代码,你可以学习到如何将 Haskell 的特性应用到实际的算法问题中,如使用高阶函数和 Monads 来管理复杂逻辑,以及如何通过模式匹配和惰性求值优化代码。同时,测试用例能帮助理解算法的输入输出格式和...

    SPOJ:我对 SPOJ 问题的解决方案 (www.spoj.com)

    SPOJ,全称为Sphere Online Judge,是一个在线的编程竞赛平台,它提供了各种算法和数据结构问题供用户解决,以提升编程技能和算法理解。在这个平台上,你可以使用多种编程语言,包括C++,来编写代码并提交解决方案。...

    spoj做题表格

    标题:“spoj做题表格”与描述“杨弋SPOJ做题表格”共同指向了在SPOJ(Sphere Online Judge)平台上的编程题目列表,这通常被用于记录和跟踪解决算法问题的进度。SPOJ是一个知名的在线裁判系统,为全球范围内的...

    SPOJ极少量的源程序。

    3. **PRIME1**:题目很可能与素数有关。需要了解素数的定义,可能需要实现快速检测素数的算法,如埃拉托斯特尼筛法或米勒-拉宾素性测试。 4. **PALIN**:这可能是指回文字符串的检测。需要理解字符串操作,如字符串...

    SPOJ:Sphere 在线裁判代码

    1. **输入处理**:SPOJ通常使用标准输入(stdin)来提供测试数据,因此你需要设计合适的输入处理机制。例如,可以使用`Scanner`类或`BufferedReader`类来读取输入。对于大量输入,`BufferedReader`通常更高效。 2. ...

    spoj-java:一些spoj问题的解决方案

    【标题】"spoj-java:一些spoj问题的解决方案"主要涵盖了使用Java编程语言解决在线判题平台Spoj上的各种算法问题。SPOJ(Sphere Online Judge)是一个全球性的在线编程竞赛平台,它提供了大量的算法题目供程序员练习...

    spoj-solutions:简单的SPOJ问题的解决方案。 看

    5. **优化效率**:考虑时间复杂度和空间复杂度,优化代码以满足SPOJ的时限要求。 这个压缩包可能包含了以上部分或全部知识点的实例代码,通过阅读和学习这些解决方案,开发者可以加深对各种算法和数据结构的理解,...

    RandomCode:Python算法,SPOJ,涂鸦

    SPOJ(Sphere Online Judge)是一个在线编程竞赛平台,它提供了大量的算法题目供参赛者用Python等语言解决。通过参与SPOJ,你可以锻炼自己的算法思维,提升解决问题的能力。 1. **基础数据结构**:Python内置了多种...

    SPOJ:应对spoj.com的挑战

    总结来说,应对SPOJ的挑战,你需要熟悉C#语言,掌握基本和高级算法,懂得代码优化,熟练处理输入输出,并利用好SPOJ平台提供的资源和社区。通过不断的实践和学习,你可以逐步提高自己在SPOJ上的竞争力。

    SPOJ.zip_SPOJ_sgu_them

    1. SPOJ-MINVEST.cpp:这可能是一个关于投资最小化成本的问题,动态规划可以用于找出最优化的投资策略,比如最小化交易费用或者最大化投资回报。 2. SPOJ-MAXSUMSQ.cpp:此代码可能解决的是在一个数组中找到最大平...

    spoj:Sphere Online Judge 的竞争性编程

    Sphere Online Judge(Spoj)是一个在线编程竞赛平台,它提供了大量的算法问题供用户解决,以提升他们的编程和算法技能。这个平台支持多种编程语言,包括C++,并且鼓励用户使用高效的算法来解决问题。"spoj:Sphere ...

    Spoj-Solutions:我的 spoj 解决方案

    1. **算法基础**:在Spoj上,你需要熟悉基础算法,如排序(快速排序、归并排序、冒泡排序等)、搜索(深度优先搜索、广度优先搜索)、动态规划、贪心算法、回溯法等,这些都是解决问题的基础。 2. **数据结构**:...

    SPOJproblems:C#中的SPOJ问题

    SPOJ(Sphere Online Judge)是一个在线编程竞赛平台,它提供了大量的算法问题供程序员解决,以提高他们的编程技能和算法理解。在这个特定的压缩包文件"SPOJproblems"中,重点是C#语言在解决SPOJ问题上的应用。下面...

Global site tag (gtag.js) - Google Analytics