1. Winning Ticket - Regular Expressions - More Exercise - C# Fundamemtals
Здравейте,
става въпрос за задача 1. Winning Ticket - More Exercise , гърмят ми 6, 7 и 8 тест и не мога да разбера къде е проблема, какъвто и вход да въведа работи правилно, но в judge ми дава 70/100. Ще съм много благодарна, ако някой ми помогне
Ето коса ми - https://pastebin.com/8h79rbas
Условие
Lottery is exciting. What is not, is checking a million tickets for winnings only by hand. So, you are given the task to create a program which automatically checks if a ticket is a winner.
You are given a collection of tickets separated by commas and spaces. You need to check every one of them if it has a winning combination of symbols.
A valid ticket should have exactly 20 characters. The winning symbols are '@', '#', '$' and '^'. But in order for a ticket to be a winner the symbol should uninterruptedly repeat for at least 6 times in both the tickets left half and the tickets right half.
For example, a valid winning ticket should be something like this:
"Cash$$$$$$Ca$$$$$$sh"
The left half "Cash$$$$$$" contains "$$$$$$", which is also contained in the tickets right half "Ca$$$$$$sh". A winning ticket should contain symbols repeating up to 10 times in both halves, which is considered a Jackpot (for example: "$$$$$$$$$$$$$$$$$$$$").
Input
The input will be read from the console. The input consists of a single line containing all tickets separated by commas and one or more white spaces in the format:
- "{ticket}, {ticket}, … {ticket}"
Output
Print the result for every ticket in the order of their appearance, each on a separate line in the format:
- Invalid ticket - "invalid ticket"
- No match - "ticket "{ticket}" - no match"
- Match with length 6 to 9 - "ticket "{ticket}" - {match length}{match symbol}"
- Match with length 10 - "ticket "{ticket}" - {match length}{match symbol} Jackpot!"
Constrains
- Number of tickets will be in range [0 … 100]
Examples
Input |
Output |
Cash$$$$$$Ca$$$$$$sh |
ticket "Cash$$$$$$Ca$$$$$$sh" - 6$ |
$$$$$$$$$$$$$$$$$$$$, aabb , th@@@@@@eemo@@@@@@ey |
ticket "$$$$$$$$$$$$$$$$$$$$" - 10$ Jackpot! invalid ticket ticket "th@@@@@@eemo@@@@@@ey" - 6@ |
validticketnomatch:( |
ticket "validticketnomatch:(" - no match |
Много благодаря, това ми беше грешката!
Hello everybody!
Although with every given input I receive the correct output, I have problem with test- 6,7 and 8 as well. I get the correct ouput with those inputs too:
@@th@@@@@@e@@m@@@@@@ - 6
@@@@@@@@@@et@@@@@@@@ - 8
Is it possible that Judge gives me only 70/100, because I don't use the second regex to count the max sequences of the repeating symbols? I used two for loops for the left and the right side in order to count the repeating sequences.
https://pastebin.com/phRuc71B
I have just founded one of my mistake- in the last if/else conditions we have to use only:
int validTheRepeatingLengthInBothSide = Math.Min(maxRightLengthOfTheSameSequences, maxLeftLengthOfTheSameSequences);
At the moment I have problem with only test Test #8 (Incorrect answer) 90/100: https://pastebin.com/phRuc71B .
If anybody has any idea about the Test 8 input, please share it. Thanks!
@Elena123456
Виждам няколко грешки в решението.
1. Няма да се изведе никакво съобщение, в случай, че печелившите символи от двете страни на билета са различни, например:
$$$$$$$$$$##########
Това се оправя лесно, като се добави един else на ред 47.
2. След като оправите горният проблем, опитайте с този вход:
$$$$$$$$##$$$$$$$$$$
Програмата ще изведе
ticket "$$$$$$$$##$$$$$$$$$$" - no match
вместо
ticket "$$$$$$$$##$$$$$$$$$$" - 8$
Грешката е в логиката на CheckRightSideForWinnerSequences/CheckLeftSideForWinnerSequences методите - липсва проверка дали текущият печеливш символ е същия, като предходния.
Има и други логически пропуски в тези методи, но преди да ги оправите, Ви препоръчвам да изтриете единия метод, защото те са идентични по функционалност и няма смисъл от повтаряне на код:
Примерно решение за 100/100.
Аз лично бих изнесъл логиката по валидация на билета изцяло в регекса, например:
Ето как изглежда решението на Java с използване на горният регекс (на C# не би трябвало да е много по-различно).
Здравейте @ MartinBG и благодаря за разясненията, и корекциите.
Умишлено не сложих във фор цикъла проверка за еднаквостта на предходния елемент за да не го усложнявам, защото виждах, че с валидацията на регекса и последваща проверка преди принтирането ще отстраня този проблем. Но да, просто не се принтира нищо в този случай: $$$$$$$$$$########## , което не е коректно.
Реших да се вслушам в съвета Ви и да махна фор циклите. Ето оптимизираното решение, което направих тази сутрин- https://pastebin.com/QJjZb30e
От това, което виждам проблема е на ред 39: " int validTheRepeatingLengthInBothSide = Math.Min(matchLeftSide.ToString().Split().ToArray().Length, matchRightSide.ToString().Split().ToArray().Length);"
Не успявам да коригирам този ред: взимах matches.Count, взимах го като дължина на стринг, като дължина на лист, като дължина на чар масив... но или получавам int validTheRepeatingLengthInBothSide=1 или е 46. А, аз искам да преброя отделните $ примерно, като трябва да се получи число от 6 до 10.
Ще разгледам и вашия регекс. Съвсем в началото се опитах да направя един общ регекс за целия билет, но така и не успях да го направя коректно, при което реших да разделя билета на две отделни части(лява и дясна) за да успея да опростя регекса.
Много моля, ако някой има възможност нека тези дни да погледне моя ред 39. Трябва да се получава число от 6 до 10. Предварително благодаря!
Поздрави! :)
@Elena123456
matchLeftSide и matchRightSide са от тип MatchCollection.
За да достъпим стойността на някоя от групите, може да използваме този синтаксис:
Ред №39 ще стане така:
А това е решението с оправени още няколко подобни грешки.
@ MartinBG, благодаря!
Изумително е колко бързо можете да вникнете от вашата логика за даден проблем в друга логика...и после и в трета логика за същия проблем. И не само да вникнете, но и да отстраните неточностите. Пожелавам си един ден и аз да успея да постигна това умение, когато помагам на някого.
Разбрах, че " matchLeftSide[0].Value " ни дава цялата колекция и винаги я достъпваме на "0", примерно @@@@@@@.
Когато е " matchRightSide[0].Value[0]" ни дава първата стойност на колекцията- първата @. Съответно ако вземем " matchRightSide[0].Value[1]" би трябвало да достъпим втората стойност от колецията, както е при масивите например.
Сега видях, че можем и без Contains() за проверките дали лявата и дясната страна са еднакви, ако директно сравняваме само първите символи от двете страни- "if(matchLeftSide[0].Value[0] == matchRightSide[0].Value[0])" и съответно "еlse if(matchLeftSide[0].Value[0] != matchRightSide[0].Value[0])"
Толкова съм удовлетворена, че с вашите корекции задачата ми е 100/100, че изобщо не съм се ядосвала за това, че никъде и в трите лекции за RegularExpression от общо над 5 часа аз не съм срещнала синтаксиса, който ми показахте. Това само говори, че една, две или дори три лекции за едно и също нещо не са достатъчни за да се обхване напълно материала и че човек трябва да учи от различни източници.
И имам едно последно питане- дали има някакво правило, кога се използва само Match и кога само MatchCollection? Забелязах вече, че има задачи, които могат да се решат и по двата начина.
Благодаря Ви за търпението, което проявявате, когато Ви задават въпроси.
@Elena123456
Радвам се, че отговорите ми са Ви от полза! :)
Използва се това, което е по-подходящо (по-удобно, по-просто, по-кратко, по-ясно) за решаване на конкретен проблем. Важно е да се знае какви са разликите между двата метода, а тук на помощ идва документацията:
Regex.Match
Regex.Matches
There is a ploblem: '@@@^^^^^^^^^^^^^^^@@. The length must be 7.
Здравейте на всички
Видях много сложни решения на тази задача и въпреки че съм сигурен че са верни (или най-правилни) на мен ми е трудно да вникна в логиката.
Аз се борих със осми тест повече от два часа, но стигнах до това хитроумно решение, ако някой има по лесно решение, ще се радвам да го сподели.
https://pastebin.com/ZDmLNAXm
Здравей Dimiter.Georgiev,
Щом решението ти минава всички тестове значи е добро.
Не мога да разбера как проверяваш дали символите са последователни?