HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyrailsMinor

Return input as a partial fraction

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
returninputfractionpartial

Problem

I need to write a function that, when given an input (string, float, or int), returns that input as a reduced partial fraction, and it needs to accept a wide array of inputs:

1.5 =>  "1 1/2"
5/2 => "2 1/2"
"1/3" => "1/3"
5 => "5"
"6 1/3" => "6 1/3"
0 => "0"


I've written this function using the Rational class, but was wondering if there were a better, more elegant solution:

def format_partial_fraction(fraction)
  if fraction.include? "/" # to handle "6 1/3" => "6 1/3" (or maybe I'll just trust user input in this case)
    fraction = fraction.split(" ").inject{|sum,x| sum.to_r + x.to_r }
  end

  rational = fraction.to_r
  if rational == 0
    return "0"
  elsif rational < 1 # e.g. "1/3"
    rational.to_s
  else # e.g. "3 1/2" or just "3"
    rational.to_i.to_s + ( rational%1 == 0 ? "" : " " + (rational%1).to_s)
  end
end


Ruby 2.0.0, Rails 3.2.13

Solution

Non-string input can lead to surprising results:

p (5/2).to_r #=> (2/1), integer division performed first
p (1.1).to_r #=> (2476979795053773/2251799813685248),  float can not be represented in binary


The last case is prevented by:

p 1.1.to_s.to_r #=> (11/10)


So I'd change rational = fraction.to_r to rational = fraction.to_s.to_r. But the first case is only handled correctly if it is a string to begin with:

p "5/2".to_r #=> (5/2)


I don't think there is a remedy for that, except accepting string or float input input only.

Code Snippets

p (5/2).to_r #=> (2/1), integer division performed first
p (1.1).to_r #=> (2476979795053773/2251799813685248),  float can not be represented in binary
p 1.1.to_s.to_r #=> (11/10)
p "5/2".to_r #=> (5/2)

Context

StackExchange Code Review Q#39671, answer score: 3

Revisions (0)

No revisions yet.