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 решение! Да се надяваме, че ще се сетя да ги ползвам тия неща и на изпита.