Here's the first solution using a whopping case statement for the fractional part. This is not ideal, but it gives an idea of what's going on in order to understand the second better solution.
Code:
def frac(num)
str = (num / 12).to_s
frac = num % 12
frac_str = case frac
when 0 then ''
when 1 then '1/12'
when 2 then '1/6'
when 3 then '1/4'
when 4 then '1/3'
when 5 then '5/12'
when 6 then '1/2'
when 7 then '7/12'
when 8 then '2/3'
when 9 then '3/4'
when 10 then '5/6'
when 11 then '11/12'
end
return [str, frac_str].join(' ')
end
I use division and modulus in the first 2 lines to find the whole number and fractional bits. Then I use a case statement on the fractional part to map to a nice string representation. The return statement uses a join to avoid having messy if/then/else statements in the event the number is divisible by 12.
Here's the second solution that gets rid of the massive case statement by utilising the mathematical concept known as the greatest common divisor.
Code:
def frac(num)
str = (num / 12).to_s
common_divisor = 12.gcd(num % 12)
frac_str = if common_divisor == 12
nil
else
[num % 12 / common_divisor, 12 / common_divisor].join('/')
end
return [str, frac_str].compact.join(' ')
end
The first line is the same as the first code sample. The second line tells me the greatest common divisor of the modulus and 12. Then I use the GCD to normalise the numerator and denominator provided the number doesn't doesn't divide by 12 entirely. There's a little bit of trickery/ugliness in the code to make sure the string formatting looks appropriate on the way out.
I hope this helps!
Bookmarks