Skip to main content
Post Made Community Wiki by Jamal
Additional information in answer was off topic
Source Link

I found quite a concise answer online that seems to be faster than the above. I haven't fully got my head round it so if someone could shed some light onto the mathematics behind this solution and why it processes faster I'd really appreciate it. Any further information on how this technique could be utilised for other problems would also be very helpful.

def total_nums(x)
    xf, nf, tf = (1..x).inject(1,:*), (1..9).inject(1,:*), (1..x+9).inject(1,:*)
    (x+10)*tf/xf/nf/10 + tf/xf/nf - 10*x - 1
end

When doing a Benchmark comparison test, it certainly shows the difference in processing speed for these two results. If I tried a greater method call than total_nums(6) for the 1st method it would take too long. Here's the result for those interested.

require 'benchmark'

def total_nums x
  return 0 if x == nil
  return 1 if x == 0

  1.upto(10 ** x).count do |i|
    s = i.to_s.chars
    t = s.sort
    s == t || s == t.reverse
  end
end


def total_nums2(x)
        xf, nf, tf = (1..x).inject(1, :*), (1..9).inject(1, :*), (1..(x + 9)).inject(1, :*)
        ( ((x + 10) * tf) /xf/nf/10) + (tf/xf/nf) - (10 * x) - 1
end
    
  
Benchmark.bm do |x|
  x.report { puts total_nums(6) }

        #=>  user     system      total        real
        #=> 12952
        #=>  2.720000   0.010000   2.730000 (  2.760713)

  x.report { puts total_nums2(6) }

        #=>  user     system      total        real
        #=> 12952
        #=>  0.000000   0.000000   0.000000 (  0.000049)
end

   

I found quite a concise answer online that seems to be faster than the above. I haven't fully got my head round it so if someone could shed some light onto the mathematics behind this solution and why it processes faster I'd really appreciate it. Any further information on how this technique could be utilised for other problems would also be very helpful.

def total_nums(x)
    xf, nf, tf = (1..x).inject(1,:*), (1..9).inject(1,:*), (1..x+9).inject(1,:*)
    (x+10)*tf/xf/nf/10 + tf/xf/nf - 10*x - 1
end

When doing a Benchmark comparison test, it certainly shows the difference in processing speed for these two results. If I tried a greater method call than total_nums(6) for the 1st method it would take too long. Here's the result for those interested.

require 'benchmark'

def total_nums x
  return 0 if x == nil
  return 1 if x == 0

  1.upto(10 ** x).count do |i|
    s = i.to_s.chars
    t = s.sort
    s == t || s == t.reverse
  end
end


def total_nums2(x)
        xf, nf, tf = (1..x).inject(1, :*), (1..9).inject(1, :*), (1..(x + 9)).inject(1, :*)
        ( ((x + 10) * tf) /xf/nf/10) + (tf/xf/nf) - (10 * x) - 1
end
    
  
Benchmark.bm do |x|
  x.report { puts total_nums(6) }

        #=>  user     system      total        real
        #=> 12952
        #=>  2.720000   0.010000   2.730000 (  2.760713)

  x.report { puts total_nums2(6) }

        #=>  user     system      total        real
        #=> 12952
        #=>  0.000000   0.000000   0.000000 (  0.000049)
end

   

I found quite a concise answer online that seems to be faster than the above.

def total_nums(x)
    xf, nf, tf = (1..x).inject(1,:*), (1..9).inject(1,:*), (1..x+9).inject(1,:*)
    (x+10)*tf/xf/nf/10 + tf/xf/nf - 10*x - 1
end

When doing a Benchmark comparison test, it certainly shows the difference in processing speed for these two results. If I tried a greater method call than total_nums(6) for the 1st method it would take too long. Here's the result for those interested.

require 'benchmark'

def total_nums x
  return 0 if x == nil
  return 1 if x == 0

  1.upto(10 ** x).count do |i|
    s = i.to_s.chars
    t = s.sort
    s == t || s == t.reverse
  end
end


def total_nums2(x)
        xf, nf, tf = (1..x).inject(1, :*), (1..9).inject(1, :*), (1..(x + 9)).inject(1, :*)
        ( ((x + 10) * tf) /xf/nf/10) + (tf/xf/nf) - (10 * x) - 1
end
    
  
Benchmark.bm do |x|
  x.report { puts total_nums(6) }

        #=>  user     system      total        real
        #=> 12952
        #=>  2.720000   0.010000   2.730000 (  2.760713)

  x.report { puts total_nums2(6) }

        #=>  user     system      total        real
        #=> 12952
        #=>  0.000000   0.000000   0.000000 (  0.000049)
end

   
Source Link

I found quite a concise answer online that seems to be faster than the above. I haven't fully got my head round it so if someone could shed some light onto the mathematics behind this solution and why it processes faster I'd really appreciate it. Any further information on how this technique could be utilised for other problems would also be very helpful.

def total_nums(x)
    xf, nf, tf = (1..x).inject(1,:*), (1..9).inject(1,:*), (1..x+9).inject(1,:*)
    (x+10)*tf/xf/nf/10 + tf/xf/nf - 10*x - 1
end

When doing a Benchmark comparison test, it certainly shows the difference in processing speed for these two results. If I tried a greater method call than total_nums(6) for the 1st method it would take too long. Here's the result for those interested.

require 'benchmark'

def total_nums x
  return 0 if x == nil
  return 1 if x == 0

  1.upto(10 ** x).count do |i|
    s = i.to_s.chars
    t = s.sort
    s == t || s == t.reverse
  end
end


def total_nums2(x)
        xf, nf, tf = (1..x).inject(1, :*), (1..9).inject(1, :*), (1..(x + 9)).inject(1, :*)
        ( ((x + 10) * tf) /xf/nf/10) + (tf/xf/nf) - (10 * x) - 1
end
    
  
Benchmark.bm do |x|
  x.report { puts total_nums(6) }

        #=>  user     system      total        real
        #=> 12952
        #=>  2.720000   0.010000   2.730000 (  2.760713)

  x.report { puts total_nums2(6) }

        #=>  user     system      total        real
        #=> 12952
        #=>  0.000000   0.000000   0.000000 (  0.000049)
end