Skip to content

Instantly share code, notes, and snippets.

rhyhann/polynomial.rb Created Dec 7, 2009

 #!/usr/bin/env ruby # Polynomial beautifier, by Othmane Benkirane # The code passes the test but why is @p4 considered as a polynomial ? # An ArgumentError should be thrown. # Oh, and... it's got a lot of unseen features. Just see my personal # specs. It's possible to have a beautiful output (2x³+3x²+10x-1) # and also several compression types: (x + 5) or (2x² -3x +5) # Also, shouldn't we do that: puts @polynomial.to_s # instead of that: puts @polynomial ? require 'enumerator' # Code class Integer def sign self >= 0 ? '+' : '-' end end class Polynomial attr_accessor :output attr_reader :compression def initialize(numbers) raise ArgumentError, 'Need at least 2 coefficients' if numbers.size < 2 numbers.shift while numbers.first == 0 @numbers,@output = numbers,:ugly self.compression = :full end def compression=(compression) @b_,@a_ = case compression when :none; [' ', ' '] when :semi; [' ', ''] when :full; ['',''] else; ['',''] end end def to_s @numbers.empty? ? '0' : numbers {|@num, @exp| [coef, exponent] unless coef.nil?}. reject {|l| l.nil?}.flatten.join end alias inspect to_s private def coef return nil if @num == 0 "#{sign}#{out_number}" end def out_number @num.abs unless (@num == 1 || @num == -1) && @exp != 0 end def sign if @exp == @numbers.size - 1 "#{@num.sign}#@a_" if @num.sign == '-' else "#@b_#{@num.sign}#@a_" end end def exponent exp = @exp.to_s return 'x' if exp=='1' return '' if exp=='0' output = case @output when :ugly; "^#{exp}" when :beautiful @@exponents ||= %w(⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹) exp.split('').map {|n| @@exponents[n.to_i]}.join end "x#{output}" end def numbers @numbers.reverse.enum_with_index.map do |num, exp| yield num, exp end.reverse end end # Test suite if \$0 == __FILE__ require 'rubygems' require 'spec' describe "Polynomial" do before do @no_one = Polynomial.new([1,1,1]) @negative = Polynomial.new([-1,-2,-3]) @zero = Polynomial.new([0,1,2,3,0,4,0]) @x1 = Polynomial.new([3,4]) @long = Polynomial.new((0..20).map{|l| l%5==0 ? 1 : 0}.reverse) [@no_one,@negative,@zero,@x1,@long].each {|p| p.compression = :none} end it 'should not show a coefficient equal to 1' do @no_one.to_s.should == 'x^2 + x + 1' end it 'should also support compacted output' do @no_one.compression = :full @no_one.to_s.should == 'x^2+x+1' end it 'should also support semi-compacted output' do @no_one.compression = :semi @no_one.to_s.should == 'x^2 +x +1' end it 'should not show + then -' do @negative.to_s.should == '- x^2 - 2x - 3' end it 'should not output zero polynomials' do @zero.to_s.should == 'x^5 + 2x^4 + 3x^3 + 4x' end it 'should not put ^1' do @x1.to_s.should == '3x + 4' end it 'should also output beautiful polynomials' do @long.output = :beautiful @long.to_s.should == 'x²⁰ + x¹⁵ + x¹⁰ + x⁵ + 1' end end Spec::Runner.run end
 \$ ruby test_polynomial.rb Loaded suite Polynomial_Test Started ..... Finished in 0.00074 seconds. 5 tests, 6 assertions, 0 failures, 0 errors \$ ruby polynomial.rb ....... Finished in 0.002794 seconds 7 examples, 0 failures
to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.