Skip to content

@rhyhann /polynomial.rb
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
#!/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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.