Решение на Polynomial от Михаил Младенов
Към профила на Михаил Младенов
Резултати
- 15 точки от тестове
- 2 бонус точки
- 17 точки общо
- 15 успешни тест(а)
- 0 неуспешни тест(а)
Код
Лог от изпълнението
Compiling solution v0.1.0 (file:///tmp/d20171121-6053-1gpavm8/solution) Finished dev [unoptimized + debuginfo] target(s) in 5.56 secs Running target/debug/deps/solution-200db9172ea1f728 running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Running target/debug/deps/solution_test-e3c9eb714e09105e running 15 tests test solution_test::test_add_poly ... ok test solution_test::test_add_poly_zero_one ... ok test solution_test::test_arithmetic_properties ... ok test solution_test::test_create_poly ... ok test solution_test::test_div_poly_f64 ... ok test solution_test::test_div_poly_f64_zero ... ok test solution_test::test_fp_comparison ... ok test solution_test::test_has_point ... ok test solution_test::test_lagrange_poly_1 ... ok test solution_test::test_lagrange_poly_2 ... ok test solution_test::test_lagrange_poly_err_eq_x ... ok test solution_test::test_mul_poly ... ok test solution_test::test_mul_poly_f64 ... ok test solution_test::test_mul_poly_f64_zero ... ok test solution_test::test_mul_poly_zero_one ... ok test result: ok. 15 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out Doc-tests solution running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
История (2 версии и 5 коментара)
Михаил качи решение на 13.11.2017 05:47 (преди почти 8 години)
Вместо да инстанцираш Polynomial
, да push-ваш коефициенти в него, и после да го trim
-ваш, би могъл да си алокираш вектор, и после просто да викнеш Polynomial::from(...)
. Това по принцип ни беше идеята -- trim-ването на коефициентите да се направи при конструиране на полинома.
Не е голяма работа, просто нещо дребно, което може леко да съкрати кода и да ти даде малко повече reliability -- ако винаги конструираш вектор по един и същ начин, и винаги го нормализираш при конструиране, ще можеш смело да викаш from
, без на всяко място, където изграждаш вектор, да мислиш дали си забравил нещо.
На пръв поглед е странно, но идеята е +
да взима ownership и да върне стойност. Има AddAssign (+=)
което е 'in place' и взима &mut self
.
Не ме притеснява, че взима ownership, a че след като го вземем няма как да го върнем (защото функцията приема два аргумента а връщаме само един полином) и освен това не правим нищо с тези обекти след като им вземем ownership (тоест ще ги оставим да умрат, защото ако се опитаме да пишем в тях компилатора се оплаква, че пипаме мютъбъл вериъбъл). Ако беше &self, &rhs старите обекти щяха да си останат. А ако беше mut self, mut rhs, поне след взимането на ownership, смъртта им нямаше да е напразна защото поне има как да ползваме алокираните за тях ресурси и да конструираме резултата в тях. Тоест нещо като sometype_t operator+(sometype_t&&, sometype_t&&) в C++ (Само като пример го давам там би било тъпо да се ползва такова нещо защото има много по мощен начин за избягване на копирания и временни обекти от такива аритметични изрази. Чрез expression templates можем в compile time да парснем дървото на израза и винаги да изберем оптималния начин за смятане избягващ максимален брой копирания).
Все пак не съм сигурен дали разбирам как точно работи това. Тоест има ли как да извлечем каквато и да е полза от това че тези обекти им взимаме ownership в тая функция, а те не са mutable?
Всъщност, можеш да дефинираш функцията като mut self
, и това няма да гръмне. В случая, параметъра е еквивалентно на деклариране на променлива, така че просто self
е все едно let self = ...
, а mut self
ще е let mut self = ...
, но и двете работят със сигнатурата. Пробвай. Признавам, че може би трябваше да го напишем в условието така, или да го обясним на някоя лекция.
И да, това, че можеш да мутираш self, означава че, на теория, не е нужно да конструираш нов полином, а можеш да използваш десния. Но да, признавам, че и на мен ми е малко неинтуитивно.
Впечатляваща работа по задачата, и отвъд нея :). Оптимизациите ми се струват малко overkill за задачката, но се радвам, че ти е била достатъчно интересна да положиш усилия да ги приложиш. Получаваш 2 бонус точки от мен за работата. Не мисля, че много ти пука за точките, но въпроса е принципен :).
Вместо да инстанцираш
Polynomial
, да push-ваш коефициенти в него, и после да гоtrim
-ваш, би могъл да си алокираш вектор, и после просто да викнешPolynomial::from(...)
. Това по принцип ни беше идеята -- trim-ването на коефициентите да се направи при конструиране на полинома.Не е голяма работа, просто нещо дребно, което може леко да съкрати кода и да ти даде малко повече reliability -- ако винаги конструираш вектор по един и същ начин, и винаги го нормализираш при конструиране, ще можеш смело да викаш
from
, без на всяко място, където изграждаш вектор, да мислиш дали си забравил нещо.На пръв поглед е странно, но идеята е
+
да взима ownership и да върне стойност. ИмаAddAssign (+=)
което е 'in place' и взима&mut self
.Не ме притеснява, че взима ownership, a че след като го вземем няма как да го върнем (защото функцията приема два аргумента а връщаме само един полином) и освен това не правим нищо с тези обекти след като им вземем ownership (тоест ще ги оставим да умрат, защото ако се опитаме да пишем в тях компилатора се оплаква, че пипаме мютъбъл вериъбъл). Ако беше &self, &rhs старите обекти щяха да си останат. А ако беше mut self, mut rhs, поне след взимането на ownership, смъртта им нямаше да е напразна защото поне има как да ползваме алокираните за тях ресурси и да конструираме резултата в тях. Тоест нещо като sometype_t operator+(sometype_t&&, sometype_t&&) в C++ (Само като пример го давам там би било тъпо да се ползва такова нещо защото има много по мощен начин за избягване на копирания и временни обекти от такива аритметични изрази. Чрез expression templates можем в compile time да парснем дървото на израза и винаги да изберем оптималния начин за смятане избягващ максимален брой копирания).
Все пак не съм сигурен дали разбирам как точно работи това. Тоест има ли как да извлечем каквато и да е полза от това че тези обекти им взимаме ownership в тая функция, а те не са mutable?
Всъщност, можеш да дефинираш функцията като
mut self
, и това няма да гръмне. В случая, параметъра е еквивалентно на деклариране на променлива, така че простоself
е все едноlet self = ...
, аmut self
ще еlet mut self = ...
, но и двете работят със сигнатурата. Пробвай. Признавам, че може би трябваше да го напишем в условието така, или да го обясним на някоя лекция.И да, това, че можеш да мутираш self, означава че, на теория, не е нужно да конструираш нов полином, а можеш да използваш десния. Но да, признавам, че и на мен ми е малко неинтуитивно.