Programming Fundamentals - Exam Preparation II (Star Wars Exam) ForceBook
Здравейте, колеги!
Пробвам се на StarWarsExam-а и последната задача, ForceBook, направо ме разби.
Искам преди да стигнем до грешките в кода ми, да споделя мнението си, че условието или по-скоро тематиката на задачата е абсурдно-объркваща. При положение, че говорим за Star Wars, всички знаем че има само 2 сили - лайт и дарк. Задачата, обаче, предполага наличието на N на брой сили, защото ако бяха само две можеше да си я решим със списъци, вместо с речник. Знам, че последната задача от тия изпити винаги е с речник, и да видях, в примерните тестове че има и Лайтър, което ме наведе на мисълта че има повече от две сили, НО въпреки това, се обърках и си пропилях адски много време само заради "украсата" на условието, която някой АДСКИ много е държал да бъде Star Wars тематика. Смятам, че е готино да се слага такива теми на условията, за гейминга ми хареса примерно, но целта на тази "тематика" е не да ни обърква, а да ни мотивира. Моля лекторите, да си подбират по правдоподобно тематиката, защото на изпит при стрес лесно може да се обърка човек само от нея.
След 88-мата минута чуденки колко аджеба сили има в смотаната галактика, реших да почна почти от начало и 75минути по-късно и стигнах до тоя код:
Условие: https://tinyurl.com/yautybec
Код: https://pastebin.com/JYDx28r3
Резултат 70/100 - един грешен и 2 лимит време.
Може ли някой да погледне калпавия ми код и да се смили да ми посочи някоя друга оптимизация/поправка?
Благодаря, предварително!
Честно казано, не виждам разлика чисто в логиката/проверките между кодовете ни.
А сигурно има, тъй като с моя получавам 2 грешни отговора, което сочи, че не е само проблема в бързината на кода.
Ти виждаш ли нещо, което би дало различен резултат?
Една разлика е , че аз ползвам отделен речник за всяка <SIDE><брой джедаи> за да пазя отделно колко човека има във всяка SIDE(или религия както аз ги наричам :) ), докато ти не. Проверих местата, където добавям/изваждам от главния речник със списъците и навсякъде си модифицирам и втория за бройката на джедаите.
Пффф, след около час и половина търсене намерих всичко. Първо трябва да използваш този separatorInd и за "религиите", защото има един тест, в който са с повече от една дума. След това: там където проверяваш poiPresent нещо не е както трябва. Направи си го ето така:
foreach (var kvp in ledger)
{
foreach (var personOfInterest in kvp.Value)
{
if (inputName == personOfInterest) // imame takuv 4ovek
{
poiPresent = true;
religionLocation = kvp.Key;
}
}
}
И накрая: в първата част от решението ( if(input.Contains("|") ) в стейтмънта if (ledger.ContainsKey(inputSide) == false) // nova religiq трябва да сложиш една проверка дали inputName не съществува някъде другаде и ако да - continue.
Пробвай сега да видим и пиши какво е станало.
Първо, ти благодаря за помощта и отделеното време! Оценявам го :)
За separatorInd - бях забравил да кача по-новия си код където направо хващам инпут с повече думи с
string[] inputArr = input.Split(new string[] { " | " }, StringSplitOptions.RemoveEmptyEntries).ToArray();
Първата грешка я остраних с поправка на foreach циклите, където търся PersonOfInterest. Наистина междинния беше излишен и не знам, защо го бях сложил :)
Втората грешка беше, че абсолютно съм пропуснал да проверя дали при несъществуваща религия, все пак го няма тоя човек някъде другаде. Явно не си чета условията, достатъчно - и друг път ми се е случвало.
Така, че ми помогна адски много! Тенкю!
Единствения проблем сега, е че получавам 100/100 само когато пробвам да събмитна на C# code, а не C# (NET.core), тъй като на Net.core ми дава 3 до 4 лимита време, а на C# всичко минава адски бързо - понякога до 3х по-бързо. На новия изпит за септември, май ще ни махнат C# code опцията и ще трябва някак си да оптимизирам скоростта.
Може би ако не ползвам 2 речника би се получило? Там ми е малко по-трудно накрая да ги преброя коя религия колко имае с ламбдата изразите, които ти ползваш.
Edit: Премахнах втория речник изцяло и получих legit 100/100 на С#(Net.core), като копирах твоята версия на принтирането -
1. ledger = ledger.OrderByDescending(s => s.Value.Count).ThenBy(s => s.Key).ToDictionary(s => s.Key, s => s.Value);
Това сам няма да се сетя как да стане, особено ThenBy не съм го ползвал никога май.
2. foreach (var religion in ledger)
{
string religionName = religion.Key;
List<string> list = religion.Value;
list.Sort();
if (list.Count>0)
{
(принитране...)
}
Изкефи ми как си го вадиш списъка в променлива и си работиш с него просто. Мн lean решение! Да се надяваме, че ще се сетя да ги ползвам тия неща и на изпита.
Няма защо. А за изпита - не се притеснявай. Това със скоростите на framework и core май е от judge, не от кода. Когато е правен този изпит в judge е нямало .NET core, след това го слагат и се получават някакви неочаквани проблеми. Но ако все пак ти се случи нещо такова, просто пусни пак същия код и виж какво ще стане. Относно проверките - както казах са много и е възможно някоя въобще да не ти хрумне (на мен тази последната ми отне няколко дни докато се сетя за нея, дори почти се бях отказал да търся накрая). Кофтито е, че не всички са написани както трябва в условието (колкото и внимателно да го четеш) и доста често са някакви гранични и невероятни случаи. Но както казах - не се притеснявай, защото изпитите вече се правят по друг начин. Тестват се знанията от курса, а не дали ще ти хрумне, че някой може да ти подаде десет пъти едно и също, или празен масив, или масив с по петнадесет интервала между елементите. Пробвай изпитите от последната инстанция (от 1-ви юли и поправката от 27-ми август). Що се отнася до сортировката и LINQ и Lambda: гледай лекциите от предишни инстанции на курса и търси във форума чужди решения за идеи (поне аз така направих). Успех!