public
Last active

  • Download Gist
polynomial.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
#!/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
testsuite.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14
$ 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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.