2

How can I simplify this piece of code?

if number < 100
    divisor = 10
elsif number < 1000
    divisor = 100
elsif number < 1000000 # 1 million
    divisor = 1000
elsif number < 1000000000 # 1 billion
    divisor = 1000000
elsif number < 1000000000000 # 1 trillion
    divisor = 1000000000
# Keep goin...
end

The point here is...

  • If the number is >= 0 and < 100 I need a divisor = 10.
  • If the number is >= 100 and < 1.000 I need a divisor = 100.
  • If the number is >= 1.000 and < 1.000.000 I need a divisor = 1.000.
  • If the number is >= 1.000.000 and < 1.000.000.000 I need a divisor = 1.000.000.
  • This keeps goin forever..

I tried a few combinations of while and pow, but I don't get the pattern here.

Thiago Belem
  • 7,732
  • 5
  • 43
  • 64
  • Looks like you have two patterns here. Think about the logic you used to decide on those values in the first place and it will probably lead to the answer (or is it not your code?) – lc. Jan 24 '13 at 06:54
  • have you tried using `for-loop` and `modulus` operator? – Mark Jan 24 '13 at 06:54
  • elsif number < 1000000 # 1 million divisor = 1000 for this you required 1000 or 100000 – Dnyan Waychal Jan 24 '13 at 07:12
  • [`Math.log10`](http://ruby-doc.org/core-1.9.3/Math.html#method-c-log10) is your friend if you know how to use it and what the domain of the `log` function is (sticking to **R** of course). – mu is too short Jan 24 '13 at 07:16
  • I have updated the question with more info, I've already tried `Math.log10`... maybe I misused it – Thiago Belem Jan 24 '13 at 07:18

4 Answers4

3
def divisor num
  10 ** (num < 1000 ? Math.log10(num).to_i : Math.log10(num).to_i / 3 * 3)
end

divisor(99) # => 10
divisor(999) # => 100
divisor(999_999) # => 1_000
divisor(999_999_999) # => 1_000_000
divisor(999_999_999_999) # => 1_000_000_000

Or, more compactly:

def divisor num
  ->a{10 ** (a < 3 ? a : a / 3 * 3)}.call(Math.log10(num).to_i)
end
sawa
  • 165,429
  • 45
  • 277
  • 381
1

try

   divisior = 10**(number.to_s.length - 1)

as per given condition
it will give you result .

Babasaheb Gosavi
  • 7,735
  • 1
  • 14
  • 14
Dnyan Waychal
  • 1,418
  • 11
  • 27
0

In your specific case, you can calculate the divisor. See Dnyans answer.

If you have a similar problem and you can't calculate the result, but want to avoid the if-elsif structure, then you could use case:

case number 
  when 0...100
    divisor = 10
  when 100...1000
    divisor = 100
  when 1000...1000000 # 1 million
    divisor = 1000
  when 1000000...1000000000 # 1 billion
    divisor = 1000000
  when 1000000000...1000000000000 # 1 trillion
    divisor = 1000000000
# Keep goin...
  else
end

To implement the < 100 is a bit more complex:

NegativeInfinity = -1.0/0.0 
case number 
  when NegativeInfinity...100
    divisor = 10
  when 100...1000
    divisor = 100
  when 1000...1000000 # 1 million
    divisor = 1000
  when 1000000...1000000000 # 1 billion
    divisor = 1000000
  when 1000000000...1000000000000 # 1 trillion
    divisor = 1000000000
# Keep goin...
  else
end

If you want to avoid to assign divisor each time, you could use the result of the case-command:

divisor = case number 
  when NegativeInfinity...100
    10
  when 100...1000
    100
  when 1000...1000000 # 1 million
    1000
  when 1000000...1000000000 # 1 billion
    1000000
  when 1000000000...1000000000000 # 1 trillion
    1000000000
# Keep goin...
  else
end

And combined with sawas answer you can make it for all values:

divisor = case number 
  when 0...100
    10
  when 100...1000
    100
  else
    (10 ** (Math.log10(number).to_i / 3 * 3))
end
Community
  • 1
  • 1
knut
  • 27,320
  • 6
  • 84
  • 112
0
x=number
divisor=10
(x/=10;divisor*=10) while x>=100
raubarede
  • 423
  • 3
  • 6