Thanks for the reviews.
I have change my code a little bit.
I now check for 1 string and at the end I check for every word the three filters
So I looks now like this:
checkForbiddenParts: word
������ "checks if a word contains some forbidden parts"
������ ^ forbiddenWords anySatisfy: [ :forbidden | word includesSubstring: forbidden ]
checkLessThen3Vowels: aString
������ "checks if a words contains less then 3 vowels"
������ ^ (aString count: #isVowel) < 3
checkOverLapping: aString
������ "checks if a string has two overlapping characters"
������ | result |
������ result := aString asArray overlappingPairsCollect: [ :a :b | a ~= b ].
������ ^ result includes: true
isNice: aCollection
������ "checks if a word is nice according to the 3 filters"
������ | answer |
������ answer := aCollection
������ ������ reject: [ :word |
������ ������ ������ (FindNiceStrings new checkForbiddenParts: word)
������ ������ ������ ������ | (FindNiceStrings new checkLessThen3Vowels: word)
������ ������ ������ ������ | (FindNiceStrings new checkOverLapping: word) not ].
������ ^ answer size
But somewhere must be a bug because the answer the code given in too high.
So I think I for a few hours/days busy to find out where the bug is.
here are the 3 filters described :
A nice string is one with all of the following properties:
- It contains at least three vowels (
aeiouonly), likeaei,xazegov, oraeiouaeiouaeiou.- It contains at least one letter that appears twice in a row, like
xx,abcdde(dd), oraabbccdd(aa,bb,cc, ordd).- It does not contain the strings
ab,cd,pq, orxy, even if they are part of one of the other requirements.
Roelof
Op 15-12-2018 om 09:37 schreef phil@highoctane.be:
Thx for those reviews.
And interesting paper.
Phil
On Sat, Dec 15, 2018, 04:20 Richard O'Keefe <raoknz@gmail.com wrote:
Starting from the top:\(0) It's not *wrong* to start a selector with a capital letter, but�� �� it is certainly unusual.(1) Intention-revealing names are good.�� That's why this name is bad.�� �� It does not *delete* anything.(2) The comment again says "delete" but nothing is deleted.�� Comments�� �� that mislead are worse than no comments.(3) An issue I have seen over and over in student code (in other�� �� programming languages) is writing regular expressions as string�� �� literals where they are used, so that every time you try a match�� �� the regular expression gets recompiled, over and over again.�� �� You're not exactly doing that, but you *are* rebuilding patterns�� �� over and over again.�� It would make more sense to hold a�� �� forbiddenPatterns collection.(4) You are saying "(coll reject: [..test..]) notEmpty", building an�� �� entire collection just to ask whether it has any members.�� What�� �� you want to know is "are there any elements of coll that do not�� �� satisfy the test", which can be expressed as�� �� (coll allSatisfy: [..test..]) not.�� (Sadly there is no�� �� #notAllSatisfy:, although #notAnySatisfy: *does* exist under the�� �� name #noneSatisfy:.(5) #match: is a highly risky way to look for a substring.�� What if�� �� you want to look for a literal # or * ?�� What if you need to�� �� look for 'Boring' but not 'boring'?�� ("Boring" is a perfectly�� �� good surname.)(6) You really don't need the "result" variable.
�� �� allowedWords�� �� �� "Answer those words which do not contain any forbiddenWord�� �� �� ��as a substring."�� �� �� ^words select: [:each |�� �� �� �� ��forbiddenWords noneSatisfy: [:forbidden |�� �� �� �� �� �� <<each includes forbidden as a substring>>]]
(7) You can find out how to do the <<part>> by looking at the methods�� �� for String.�� You will find several candidate methods.(8) Of course, if there are W words and F forbidden words, in the�� �� worst case you'll do W*F substring inclusion tests.�� This is not�� �� good.�� "Multiple pattern matching" is a much-studied problem,�� �� see for example Wu and Manber's paper�� �� There is more recent work also.
�� �� Does anyone know whether there's a multiple pattern algorithm for�� �� Pharo?�� One could always fall back on ternary search trees...
On Fri, 14 Dec 2018 at 05:13, Roelof Wobben <r.wobben@home.nl> wrote:
Hello, I have this code : ��FindAndDeleteWordsWithForbiddenParts "deletes all the words that contain forbidden parts" | result | result := words select: [ :word | [ (forbiddenWords reject: [ :forbidden | '*' , forbidden , '*' match: word ]) isNotEmpty ] on: NotFound do: [ false ] ]. ^ result but I see warnings that I have to use a stream instead of string concentation. Anyone hints how to do so ? Roelof