fork download
  1. def palindromic_numbers_v1
  2. Enumerator.new do |y|
  3. y << 0
  4. (1..Float::INFINITY).lazy.map {|k| [10 ** (k - 1), 10 ** k - 1].map(&:to_s)}.each do |b, e|
  5. (b..e).each {|s| y << (s + s.reverse[1..-1]).to_i}
  6. (b..e).each {|s| y << (s + s.reverse).to_i}
  7. end
  8. end
  9. end
  10. def palindromic_numbers
  11. arevb = -> a, b {b == 0 ? a : arevb.(a * 10 + b % 10, b / 10)}
  12. Enumerator.new do |y|
  13. y << 0
  14. (1..Float::INFINITY).lazy.map {|k| [10 ** (k - 1), 10 ** k - 1]}.each do |b, e|
  15. (b..e).each {|x| y << arevb.(x, x / 10)}
  16. (b..e).each {|x| y << arevb.(x, x)}
  17. end
  18. end
  19. end
  20. f = -> n {
  21. ps = palindromic_numbers.each_cons(2).find {|a, b| a <= n && n <= b}
  22. ps.map {|x| [(n - x).abs, x]}.sort.uniq.group_by(&:first).first.last.map(&:last)
  23. }
  24. p [0, 17, 100, 1000, 10000].map {|n| [n, f.(n)]}
  25.  
  26. require 'benchmark'
  27. Benchmark.benchmark(Benchmark::CAPTION, 12) do |x|
  28. n = 500000
  29. x.report("v1(#{n}): ") {palindromic_numbers_v1.take(n)}
  30. x.report("v2(#{n}): ") {palindromic_numbers.take(n)}
  31. x.report("v1(#{n}): ") {palindromic_numbers_v1.take(n)}
  32. x.report("v2(#{n}): ") {palindromic_numbers.take(n)}
  33. p palindromic_numbers_v1.take(n) == palindromic_numbers.take(n)
  34. end
  35. #p palindromic_numbers_v1.lazy.zip(palindromic_numbers.lazy).map {|v1, v2| [v1 - v2, v1, v2]}.take(50).force.sort
  36.  
Success #stdin #stdout 3.15s 23904KB
stdin
Standard input is empty
stdout
[[0, [0]], [17, [22]], [100, [99, 101]], [1000, [999, 1001]], [10000, [9999, 10001]]]
                   user     system      total        real
v1(500000):    0.531450   0.000000   0.531450 (  0.534889)
v2(500000):    0.517562   0.000000   0.517562 (  0.520639)
v1(500000):    0.508999   0.000000   0.508999 (  0.512154)
v2(500000):    0.508406   0.000000   0.508406 (  0.511309)
true