[Exam]Java Fundamentals 04.10.2015
Та така, колеги. Кажете си мнението за изпита. Май се сбъдна това, което enevlogiev намекна в една тема, доста тежички задачи. Четвърта май е най-лесна противно на обичайната подредба - аз обаче на нея доста се запънах понеже реших да я правя ООП, направих си клас за дракони, които исках функционално да подредя, обаче се оказа че Java по default ползва hashMap при такъв подход, което ми прецакваше подребата. Вкарването в употреба пък на LinkedHashMap се оказа извън възможностите ми и след половин-един час изгубен в stackoverflow си ги хванах ръчно и си ги набих в един такъв мап, останалото беше лесно. Първа също не беше трудна, но едва след малко борба успях да открия правилен регекс, който да не хваща каквото не трябва в кавичките също взех 100. След като направих тези двете, погледнах какви са резултатите на втора и трета и след като не видях никой с каквито и да е точки на Счетоводната, се захванах с трета, за което по-скоро съжалявам. Нещо обаче не можах да измисля алгоритъма за обхождане, освен това изникна ситуация, поради която трябваше и да си тръгна по-рано, така че си останах с 2 задачи. Но с оглед на трудността честно казано съм доволен. На поправката когато Java ще е преди OOP ще се явя да си взема максимума и така :D
Първа - http://pastebin.com/EQw5gDMm
Четвърта - http://pastebin.com/8TwzrKC1
Причината на 2-ра да минават нулевите и никои други, е че всички състезателни тестове са комплексни. Проблемът най-вероятно е в смятането на заплатите и/или другаде. Има някакви варианти да се изкарат частични точки (30 с грешки в сметките или 60 с бавна имплементация), но като цяло е или 0, или 100.
Примерно, на ред 26 при деленето трябва да ползваш RoundingMode.UP. Друго в момента трудно ще видя, но не е само това. Общо взето трябва да се чете с лупа условието, защото всяко едно изречение носи важна информация как да се подходи.
Едит: Увеличението на заплатата трябва да го приложиш върху първоначалната сума, а не върху дневната. И това има значение...
И при мен минаха само нулевите. Но аз я решавам доста по различно и имам доста грешки. Общо взето правя клас Employee с полета заплата и работни дни. Тъпча ги в един LinkedList, за да мога да ползвам removeFirst(), когато уволнявам. Дните почват от 1 и в началото на цикъла минавам през листа и добавям на всеки работник по един ден. Съответно за повишение филтрирам и повишавам. Мисля, че заради removeFirst() ми гърмят времеви тестове, но бързах и това беше най-лесният вариант. При тебе не мога да схвана много много за какво става реч, но мисля че hired и fired трябва да са long.
Тестовете са такива, че ще мине и с int задачата. Проблемът е, че ако се разглеждат всички служители поотделно, получаваме много голяма колекция, която яде много време, за да се обходи (неколкократно за всяка команда). Ако вместо клас Employee се направи EmployeeGroup, който да пази и брой работници, ще е доста по-бързо. Съвсем малко се усложнява процедурата по уволняване при този вариант.
Изпитът беше на ниво Advanced или по-високо. Съжалявам, но тук стана голямо объркване. Курсът бе преименуван на "Java Fundamentals", което само по себе си е еквивалент на "Java Basics" и обективно погледнато не би трябвало да промени нищо по материала (както и стана), но ето че изпитните задачи се оказаха на доста по-високо ниво. Лекциите бяха приятни и леки, с нищо по-сложно от basics ниво. Нямаше подготовка за толкова тежки задачи. Ако не ме разбирате, опитайте да се подготвите за Advanced C# със задачи от C# Basics... най-вероятно ще увиснете с 1 решена задача в най-добрия случай. Много ви моля за коректност! Ако ще са подобни задачите от тук нататък, нека има някакъв вид подготовка и да се смени курсът на Advanced Java или нещо от сорта. Ако и тук не ме разбирате, проверете значението на думичката "fundamental" и след това прегледайте задачите и ще се убедите, че има голямо несъответствие.
Разбирам, че сме първа група от ниво Fundamental и съм напълно съгласен, че трябва да ни тествате, но това беше прекалено.
Сега я реших втора - всъщност не е трудна, но има някои tricky части в работата с BigDecimal, както и в това как ще си пазиш данните - аз си направих клас, поради което с многото обхождане някои тестове гърмят за време - но това може да се оправи и не ми се занимава. Имах грешка със закръгляването при daily salary, но я оправих.
http://pastebin.com/V9MVzqxx
Това с времето се получава, както каза Фил, ако в колекцията на всеки ред пазиш по едно Employee, става много бавно обхождането, защото можеш да получиш до 3 млрд емплоита, което значи че още на 1ви ден можеш да напълниш листа адски много, да не кажа препълниш. Само ги местиш да се пазят на групи и си идеален. Иначе супер решение :)
На тази задача и липсваше нулев тест, в който минава цяла година, за да се видят моментите на даване на заплата и моментите на вдигане на заплатата.
Премахнах единия foreach, за да спестя итерации и промених малко какво държи класа, но сега пък джъджа ми прави номера - с един и същ код ту ми гърми за време, ту дава comiple time error, а понякога и грешни отговори
http://pastebin.com/5svGq38G
ей тази част трябва да я извадиш от условието
day%30==0;
но ще гърми за време
Отделно от това 12 месеца по 30 дена трудно ще станат 365 дни годишно, както е написал Роял задачата
Мерси да, не бях видял че не се влиза в този if.
Сега оправих това, както и вече работя с групи, но нещо пак не е наред хаха. Странно. Заплатите се индексираха на база оригиналната заплата или спрямо новата. Казаха нещо на изпита, но не помня.
http://pastebin.com/LF1Cc3Qy
Работата е там, че не на 365тия ден в годината, а на 365тия за конкретния работник (в случая група от работници) се прави повишението. И заплатата на тази група се качва с 0,6% демек се умножава по 1,006.
Как бих подходил аз към задачата.
1. Наемам работници на ден 0
2. Почвам итерация по колекцията с работници (Списък, Свързан списък, опашка, каквото съм избрал на момента)
3. В итерацията качвам дните на работниците. Новонаетите ще станат на ден 1, както се очаква, а останалите ще пораснат с 1 ден
4. Проверявам дали съответната група работници не е стигнала 365 дни (employeeGroup.days % 365 == 0)
4.1. Ако да, им умножавам заплатата по 1,006
5. Проверявам дали денят (итерацията) не е кратна на 30 (days % 30 == 0)
5.1. Ако да, то тогава изчисляват дневната заплата на текущата група през която минавам, умножавам я по дните които са работили и по групата работници за този ден и я махам от капитала. Също така, това изчисляване колко дни са работили според мен трябва да се направи само веднъж - първия месец в който са наети. После е ясно че всеки следващ месец след като веднъж са получили заплата ще са работили по 30 дни, няма как да се окаже че първия месец са работили 12, а втория 14. Първия може да са работили 12, но втория задължително ще са работили 30. Така, че тук една булева променлива дали на тази група вече им е плащана заплата или другия вариант е, ако дните им са по-големи от 30, да приемем че ще плащаме само за 30 (Math.min(employee.days, 30))
6. Проверявам дали имам да гоня работници. Ако имам да гоня проверявам дали на текущата итерация групата има толкова работници. Ако има - махам толкова и казвам, че нямам вече да гоня. Ако няма - слагам ги на 0 за тази група и това което пада под нулата като остатък, го слагам на променливата, която контролира колко имам да гоня.
7. Връщам се на следващата итерация около работниците.
Така общо взето само с едно завъртане около работниците могат да се изчислят всичките неща, вместо колекцията да се обикаля за всяка зависимост по веднъж.
Супер, мерси - дам това беше проблема - вече всичко е 6.
http://pastebin.com/Pm2xjAZG
Съгласен съм, че може да се оптимизира итерирането, но като ги групираме така или иначе броят елементи намалява драстично, та не е болка за умиране.
Пробвах да реша трета задача тази вечер. Уж тръгна както трябва, но не мога да отлепя от 50 точки. Ако може някой да погледне къде греша:
https://github.com/EBojilova/Java/blob/master/ExamPreparation/src/arrays/DragonTrapEB.java
Яд ме е че не съм хванала да решавам тази вместо втора, поне 30-50 точки отогоре щях да имам.
Две грешки:
1) На ред 44 и 45 принтираш и спираш програмата ако за текущата команда няма припокриване между квадрата и матрицата. Трявбва просто да преминеш към следващата команда с continue
2) Не смяташ вярно броя променени символи. Трябва да се преброят клетките, които са с променена стойност като сравниш оригиналната матрица и финалната след всички завъртания.
Да прави си за continue, но пак дава 50 точки.
Аз уж броя промените, в rotateMatrix. Там преди да сетна промянта правя проверка:
Няма как да броиш промените текущо, защото след няколко завъртания в дадена клетка може да попадне пак същият символ. В отделни случаи се получава, че повече символи са сменили стойността си, отколкото е размерът на матрицата. Единственият начин е да пазиш оригиналната матрица и да сравняваш накрая.
Да това е било. Не съм допрочела условието и си броя всеки път като има промяна. Благодаря много :)
Много се надявам да се намери някой добричък колега да погледне къде е грешката в моя Dragon Accounting.
Двама души се опитваме да намерим грешка в логиката и не успяваме.
Най-вероятно е нещо с изплащането на заплатите или уволняването на хората, защото при първия тест не би трябвало да имам фалит, а аз банкрутирам след второто изплащане на заплати.
Предварително Ви благодаря за отделеното време.
https://github.com/aababyy/DragonAccounting/blob/master/P02_DragonAccounting.java
checkForRaises трябва да се прави на 365 дни на конкретен работник, а не на 365 дни от създаването на фирмата. Трябва да пазиш още нещо за работниците и то е колко дни имат в компанията.
Royal е прав, но и на други места ще трябва да пипнете. И аз бях тръгнала да пазя дневната надница, но не ми се получи.
Моето решение е аналгочно на вашето, но не съм го изнесла в методи, можеш да погледнеш.
https://github.com/EBojilova/Java/blob/master/ExamPreparation/src/DragonAccountingExam.java
Има ги и тестовете в качени в страницата на курса.
Много Ви благодаря за отговорите.
Това колко дни има група работници в компанията го пазя - това отговаря на индекса на List<Long> employeesCount + 1 /това е колекцията, в която се пазят бр. работници, назначени през всеки конкретен ден - на всяка итерация вмъквам броя назначени работници на индекс 0 и съответно когато уволнявам изтривам данните от последния /последните/ индекс/и//.
Може ли да има увеличение на заплатата, ако от създаването на фирмата не са минали 365 дни и респективно никой работник не е работил в нея поне 365 дни?
Пробвах да реша втора задача, но получавам разлика в резултата след запетаята на всички тестове, не мога да разбера къде е грешката, мисля че е от закръгляването. http://pastebin.com/aWwzWnQU
Мерси много, поправих го и получих 100/100.
Месечните заплати ги пази в чист вид, не ги закръгляй. Само дневната фракция. А дневната фракция се зичислява до ДЕВЕТИЯ НАГОРЕ и псоле се реже до СЕДМИЯ. В случая видях само setScale(7, up). А и подозирам, че не си спазил формулата . ((salary / 30) * totalWorkingDaysThatMonth).
При теб по-скоро е salary * (totalWorkingDays / 30), което когато става въпрос за подобни закръгляния със сигурност ще даде различен резултат ако го сметнеш по друг начин.
Мисля, че ако делиш БигДесимали, ще ти даде в метода за деление да кажеш до къде да изчислява, което горе долу ще иззглежда така divide(num, 9, BigDecimal.ROUND_UP).setScale(7, BigDecimal.ROUND_DOWN)