Трета задача е супер интересна и съм убеден, че имате ред въпроси по нея.
Слушаме :)
Трета задача е супер интересна и съм убеден, че имате ред въпроси по нея.
Слушаме :)
Вторият пример за derive от условието:
Expr.parse('2 * x + 3 * y').derive(:y) => Expr.parse('2')
е сгрешен.
Съвършено прави си. Оправих го.
Нужно ли е да опростяваме Expr.parse('-(-x)') или може да се разминем и без това?
Отговорих си на въпроса - не.
Ако подадем Expr.parse('x * 0').evaluate, какво би трябвало да връща 0 или грешка?
Според мен трябва да връща грешка, защото ако автоматично се правеше simplify в Expr.parse, нямаше да се налага да е достъпен като отделен метод.
Поправка: Не бях видял отговора на Красимир.
Въпрос: може ли да има следното [:variable, [other expression]] или нещо от сорта?
 [:number, 1]    # Число
 [:variable, :x] # Променлива
 [:+, a, b]      # Сбор
 [:*, a, b]      # Произведение
 [:-, a]         # Отрицание
 [:sin, a]       # Синус
 [:cos, a]       # Косинус
:x е променлива, а a и b са s-expression-и. Т.е. не може.
Някой друг има ли проблеми с repl.rb. Макар че си инсталирах treetop, в конзолата ми излиза съобщение, че липсват файлове от него?
Доколкото видях, никъде не е написано, но parser.treetop трябва да е в папката, в която са repl.rb и solution.rb.
Поне при мен така се оправи проблемът.
Да, repl си генерира парсера по време на рънтайм чрез "Treetop.load 'parser'".
x=10 ERROR: NameError => uninitialized constant InteractiveShell::Expr
И в задачата се пита какво съм успяла да объркам.
Вероятно repl нe открива дефиниция на Expr (решението ти не е в solution.rb или дефиницията на Expr не е top-level, а примерно в някакъв модул)
Май има грешка при условието. В идеите за имплементация пише:
"Също така, открихме, че е много полезно да дефинираме операторите *, + и @- върху базовия клас."
Може би става дума за -@? 
Това с оператора е оправено, благодарение на Георги, който направи PR в GitHub.
А #simplify и #derive масив ли трябва да връщат, или Expr? И какъвто и да е отговора, #simplify, който е сведен само до стойност [:number, стойност] ли трябва да върне или отново Expr?
Примери как трябва да работи #derive:
    Expr.parse('x * x').derive(:x)         => Expr.parse('x + x')
    Expr.parse('2 * x + 3 * y').derive(:y) => Expr.parse('3')
    Expr.parse('sin(x)').derive(:x)        => Expr.parse('cos(x)')
Т.е. #derive трябва да връща каквото връща #parse (каквото връща и #build).
И понеже "резултатът трябва да е опростен със #simplify", значи и #simplify връща каквото връща #parse, доколкото мога да съобразя от втория пример.
Относно #evaluate, резултатът е число, съгласно:
    Expr.parse('x * 2 + y').evaluate(x: 3, y: 4) # => 10
Аз имам въпрос за Expr#simplify - x + x до 2 * x ли се опростява или се приема, че не може да се опрости? А и x + 2*x до 3 * x ли се опростява?
Освен това за Expr#== сравнява опростените изрази или самите изрази. Например
Expr.parse('x * 2') == Expr.parse('x + x')
true или false е?
Моето виждане:
Условието за #derive гласи:
"Резултатът трябва да е опростен със #simplify". 
От друга страна единия от примерите за работата на #derive е следният:
    Expr.parse('x * x').derive(:x)         => Expr.parse('x + x')
Т.е. x + x е опростен израз, понеже е бил обработен със #simplify. По тази логика и x + 2 * x би трябвало да не се нуждае от опростяване.
Относно #==, ето какво гласи условието: "Изразите се сравняват символично."
И понеже x * 2 и x + x не изглеждат по един и същи начин, следва
    Expr.parse('x * 2') == Expr.parse('x + x')
да се оцени до false.
В подкрепа на горното, миналата сряда, когато говорихме за задачата, имаше пример с производната на x * x * x, която се получава в особено красивия вид x * x + x * (x + x) или друг подобен и еднакво красив, и беше казано, че не се очаква да я опростяваме. Но, ако имаш желание, никой няма да ти се разсърди 
Може би въпроса е малко странен, но все пак трябва ли да опростяваме (x+2)+(x+3) до 2x+5
А по-скоро, грешка ли е , ако върнем такъв резултат? :D Не съм убеден, как ще бъде тествано без друга "symbolic math" библиотека.
Трябва да сте влезли в системата, за да може да отговаряте на теми.