-
-
Save RLGGHC/b4f03272a3657357c25b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# polynomial.rb | |
# | |
# This is the solution to RPCFN: Ruby**Fun (#4) | |
# (http://rubylearning.com/blog/2009/11/26/rpcfn-rubyfun-4/). | |
# | |
# Here we have two classes: Polynomial and Term. | |
# | |
# - Polynomial is pretty simple. On contruction, it accepts an array | |
# containing the polynomial's coefficients | |
# - Polynomial#to_s calls Polynomial#generate just the first time it is | |
# called | |
# - Polynomial#generate populates @terms and injects exponents into | |
# place | |
# - Each Term instance on @terms always holds the coefficient and exponent | |
# numbers in spite of having special cases for zeros or ones and thus no | |
# need to print them | |
# - Term#to_s covers the special cases. It filters the output mostly | |
# with regular expresions: no arithmetics needed | |
# | |
# José Sazo -- jose.sazo@gmail.com | |
class Polynomial | |
attr_reader :coefficients, :terms, :degree | |
def initialize(array) | |
@coefficients = array | |
@degree = @coefficients.length | |
@terms = [] | |
raise ArgumentError, 'Need at least 2 coefficients' unless @degree > 1 | |
end | |
def generate | |
@coefficients.each do |c| | |
@terms << Term.new(c) | |
end | |
@terms.inject(@degree - 1) do |n, term| | |
term.exponent = n | |
n - 1 | |
end | |
end | |
def to_s | |
generate if @terms.empty? | |
output = @terms.join.sub(/^\+/, '') | |
return "0" if output.empty? | |
output | |
end | |
end | |
class Term | |
attr_accessor :coefficient, :exponent | |
def initialize(coefficient) | |
@coefficient = coefficient | |
end | |
def to_s | |
s = @coefficient.to_s + 'x^' + @exponent.to_s | |
s = '+' + s unless @coefficient < 0 | |
s.slice!("1") if @coefficient.abs == 1 and not @exponent.zero? | |
s.sub!(/x\^1$/, 'x') | |
s.sub!(/x\^0$/, '') | |
return '' if @coefficient.zero? | |
return s | |
end | |
end | |
### Solution code ends here ### | |
### Testing code begins here ### | |
# | |
# Added my own test cases and adapted the code for MiniTest (Ruby | |
# 1.9.1's Test::Unit replacement) from | |
# https://gist.github.com/280aa4797a580fb8ae75 | |
require 'minitest/unit' | |
MiniTest::Unit.autorun | |
class Polynomial_Test < MiniTest::Unit::TestCase | |
def setup | |
@p1 = Polynomial.new([-3,-4,1,0,6]) | |
@p2 = Polynomial.new([1,0,2]) | |
@p3 = Polynomial.new([-1,-2,3,0]) | |
@p4 = Polynomial.new([0,0,0]) | |
@p5 = Polynomial.new([3,-2,+1]) | |
@p6 = Polynomial.new([-43,0,5,0,-1]) | |
@p7 = Polynomial.new([2,11]) | |
end | |
def test_first_negative | |
assert_equal("-3x^4-4x^3+x^2+6", @p1.to_s) | |
end | |
def test_simple | |
assert_equal("x^2+2", @p2.to_s) | |
end | |
def test_first_minus_one | |
assert_equal("-x^3-2x^2+3x", @p3.to_s) | |
end | |
def test_all_zero | |
assert_equal("0", @p4.to_s) | |
end | |
# Added by me | |
def test_last_plus_one | |
assert_equal("3x^2-2x+1", @p5.to_s) | |
end | |
# Added by me | |
def test_last_minus_one | |
assert_equal("-43x^4+5x^2-1", @p6.to_s) | |
end | |
# Added by me | |
def test_last_eleven | |
assert_equal("2x+11", @p7.to_s) | |
end | |
def test_error | |
e = assert_raises(ArgumentError) { Polynomial.new([1]) } | |
assert_match(/Need at least 2 coefficients/, e.message) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment