From 037c34b38e228d3eb05256a797d7ca465959dcdf Mon Sep 17 00:00:00 2001 From: Slavasil Date: Mon, 13 Apr 2026 19:58:40 +0300 Subject: [PATCH] add substitution and differentiation --- lib/ruby_algebra/interpreter.rb | 2 +- lib/ruby_algebra/parser.rb | 9 ++++++++- lib/ruby_algebra/polynomial.rb | 32 ++++++++++++++++++++++---------- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/lib/ruby_algebra/interpreter.rb b/lib/ruby_algebra/interpreter.rb index f8e8098..d9228cc 100644 --- a/lib/ruby_algebra/interpreter.rb +++ b/lib/ruby_algebra/interpreter.rb @@ -50,7 +50,7 @@ module RubyAlgebra @locals[command.lhs] = result return "#{command.lhs} = #{result}" when :subs - result = operand1.evaluate(operand2) + result = operand1.substitute(operand2) @locals[command.lhs] = result return "#{command.lhs} = #{result}" end diff --git a/lib/ruby_algebra/parser.rb b/lib/ruby_algebra/parser.rb index 0c8f328..12c6419 100644 --- a/lib/ruby_algebra/parser.rb +++ b/lib/ruby_algebra/parser.rb @@ -261,10 +261,17 @@ module RubyAlgebra raise ParserError, "unexpected token #{n.type}, expected =" end n = tokenizer.next_token + unless n.type == :num || n.type == :plus || n.type == :minus + raise ParserError, "unexpected token #{n.type}, expected -, + or number" + end + if n.type == :plus || n.type == :minus + negative = true if n.type == :minus + n = tokenizer.next_token + end unless n.type == :num raise ParserError, "unexpected token #{n.type}, expected number" end - substitutions[variable] = n.value + substitutions[variable] = if negative then -n.value else n.value end end n = tokenizer.next_token unless n.type == :paren && n.closing == true diff --git a/lib/ruby_algebra/polynomial.rb b/lib/ruby_algebra/polynomial.rb index 7c2fb9e..c8ab8bd 100644 --- a/lib/ruby_algebra/polynomial.rb +++ b/lib/ruby_algebra/polynomial.rb @@ -33,16 +33,12 @@ module RubyAlgebra result end - def diff - raise NotImplementedError + def diff(variable) + Polynomial.new(@terms.map { |term| term.diff(variable) }) end def substitute(values) - result = 0 - @terms.each do |term| - # ... - end - result + Polynomial.new(@terms.map { |term| term.substitute(values) }) end def +(other) @@ -190,12 +186,28 @@ module RubyAlgebra end end - def diff(var) - raise NotImplementedError + def diff(variable) + return Term.new if @variables[variable].nil? + new_coeff = @coeff + new_variables = @variables.filter { |var, power| var != variable } + unless @variables[variable] == 1 + new_coeff *= @variables[variable] + new_variables[variable] = @variables[variable] - 1 + end + Term.new(new_coeff, new_variables) end def substitute(values) - raise NotImplementedError + new_coeff = @coeff + new_variables = {} + @variables.each do |var, pow| + if values[var].nil? + new_variables[var] = pow + else + new_coeff *= values[var] ** pow + end + end + Term.new(new_coeff, new_variables) end def +(other)