Профил
Loading...
Taniaaleksandrova avatar Taniaaleksandrova 5 Точки

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

Тагове:
1
Fundamentals Module
direct avatar direct 15 Точки

Здравей, не мога да тествам кода, защото съм JS, но при тези тестове най-вероятно не си съобразил следните сценарии:

@@th@@@@@@e@@m@@@@@@ - трябва да е 6 резултатът, а не 8

@@@@@@@@@@et@@@@@@@@ - трябва да е 8, а не 10

1
Taniaaleksandrova avatar Taniaaleksandrova 5 Точки

Много благодаря, това ми беше грешката!

2
Elena123456 avatar Elena123456 168 Точки

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

0
Elena123456 avatar Elena123456 168 Точки

 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!

0
26/11/2020 01:09:15
MartinBG avatar MartinBG 3701 Точки

@Elena123456

Виждам няколко грешки в решението.

1. Няма да се изведе никакво съобщение, в случай, че печелившите символи от двете страни на билета са различни, например:

$$$$$$$$$$##########

Това се оправя лесно, като се добави един else на ред 47.

2. След като оправите горният проблем, опитайте с този вход:

$$$$$$$$##$$$$$$$$$$

Програмата ще изведе

ticket "$$$$$$$$##$$$$$$$$$$" - no match

вместо

ticket "$$$$$$$$##$$$$$$$$$$" - 8$

Грешката е в логиката на CheckRightSideForWinnerSequences/CheckLeftSideForWinnerSequences методите - липсва проверка дали текущият печеливш символ е същия, като предходния.

Има и други логически пропуски в тези методи, но преди да ги оправите, Ви препоръчвам да изтриете единия метод, защото те са идентични по функционалност и няма смисъл от повтаряне на код:

if (regexForWinningTicket.IsMatch(leftSide) && regexForWinningTicket.IsMatch(rightSide))
{
    CheckSideForWinnerSequences(leftSide, out var maxLeftLengthOfTheSameSequences,
        out var leftWinningSymbols);
    CheckSideForWinnerSequences(rightSide, out var maxRightLengthOfTheSameSequences,
        out var rightWinningSymbol);

    int validTheRepeatingLengthInBothSide = Math.Min(maxRightLengthOfTheSameSequences,
        maxLeftLengthOfTheSameSequences);
   
    //...
}


private static void CheckSideForWinnerSequences(string side,
    out int maxLengthOfTheSameSequences,
    out char winningSymbol)
{
   //....
}

 

Примерно решение за 100/100.

 

Аз лично бих изнесъл логиката по валидация на билета изцяло в регекса, например:

(?=.{20}).*?(?=(?<ch>[@#$^]))(?<match>\k<ch>{6,}).*(?<=.{10})\k<match>.*

Ето как изглежда решението на Java с използване на горният регекс (на C# не би трябвало да е много по-различно).

3
26/11/2020 03:31:53
Elena123456 avatar Elena123456 168 Точки

Здравейте @ 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. Предварително благодаря!

Поздрави! :)

1
MartinBG avatar MartinBG 3701 Точки

@Elena123456

matchLeftSide и matchRightSide са от тип MatchCollection.

За да достъпим стойността на някоя от групите, може да използваме този синтаксис:

matchCollection[groupIndex].Value // това ни връща стринга на групата с индекс groupIndex, например "$$$$$$"

 

Ред №39 ще стане така:

 

int validTheRepeatingLengthInBothSide = Math.Min(
    matchLeftSide[0].Value.Length,
    matchRightSide[0].Value.Length);

А това е решението с оправени още няколко подобни грешки.

 

1
Elena123456 avatar Elena123456 168 Точки

@ 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? Забелязах вече, че има задачи, които могат да се решат и по двата начина.

Благодаря Ви за търпението, което проявявате, когато Ви задават въпроси.

1
26/11/2020 22:25:24
MartinBG avatar MartinBG 3701 Точки

@Elena123456

Радвам се, че отговорите ми са Ви от полза! :)

 

И имам едно последно питане- дали има някакво правило, кога се използва само Match и кога само MatchCollection? Забелязах вече, че има задачи, които могат да се решат и по двата начина.

Използва се това, което е по-подходящо (по-удобно, по-просто, по-кратко, по-ясно) за решаване на конкретен проблем. Важно е да се знае какви са разликите между двата метода, а тук на помощ идва документацията:

 

Regex.Match 

Searches an input string for a substring that matches a regular expression pattern and returns the first occurrence as a single Match object.

 

Regex.Matches

Searches an input string for all occurrences of a regular expression and returns all the matches.

Returns

MatchCollection

A collection of the Match objects found by the search. If no matches are found, the method returns an empty collection object.

 

1
Aykut avatar Aykut 3 Точки

There is a ploblem: '@@@^^^^^^^^^^^^^^^@@. The length must be 7.

0