Instantly share code, notes, and snippets.

# hso/josesazo.rbSecret Created Nov 26, 2009

 # 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