Code Golf: Smiley Faces
It's Friday and a long weekend is upon us, so let's have a round of code golf!
Nowadays, it's rare to find a text message without at least one emoji. 😃😄😎🙂😊😀😁😆😂
But back in the day, people had to be creative to express their emotions in text. They would use emoticons, which are symbols made up of keyboard characters :^)=])B).
Our challenge for today is to create a function that receives a string as argument and returns the total number of smiling faces or happy faces.
Each smiley face must have one smiling mouth, which should be marked with ), ], }, D or >.
A smiley face can have a pair of eyes but it does not have to. Valid characters for eyes are :, ;, 8, B or =.
A nose is optional, and can be represented these characters: -, ^, c, o and ~.
Valid smiley face examples:
:) :D ;-D :~) :‑) :-] =)
:] :-> :> 8-) :D 8‑D )
8) :-} :} :o) :c) :^) =]
:‑D 8D =D B^D
Input
"count how many smiley faces are here :)"
Output
1
Note
Rules
The signature of the contest entry MUST be:
Class codeGolf.SmileyFace Extends %RegisteredObject { ClassMethod Count(i As %String) As %Integer { q 0 // Your solution here } }It is forbidden to modify class/signature, including but not limited to:
- Adding inheritance
- Setting default argument values
- Adding class elements (Parameters, Methods, Includes, etc).
It is forbidden to refer to non-system code from your entry. For example, this is not a valid entry:
ClassMethod Build(f As %Integer) { W ##class(myPackage.myClass).test(a) }The use of
$ZWPACKand$ZWBPACKis also discouraged.You can use this test case:
Class codeGolf.unittests.SmileyFace Extends %UnitTest.TestCase { Method TestSolutions() { Do $$$AssertEquals(##class(codeGolf.SmileyFace).Count(")s).:D :~) ;~D :) xD"), 7) Do $$$AssertEquals(##class(codeGolf.SmileyFace).Count(""), 0) Do $$$AssertEquals(##class(codeGolf.SmileyFace).Count(":):(':D:O:;"), 2) Do $$$AssertEquals(##class(codeGolf.SmileyFace).Count("let's put a smile on that face :o)"), 1) Do $$$AssertEquals(##class(codeGolf.SmileyFace).Count("(smiley)"), 1) Do $$$AssertEquals(##class(codeGolf.SmileyFace).Count("12 weirds :] :-> :> 8-) 8) :-} :} :o) :c) :^) =] =)"), 12) Do $$$AssertEquals(##class(codeGolf.SmileyFace).Count(";] ;) ;-) winky"), 3) Do $$$AssertEquals(##class(codeGolf.SmileyFace).Count("B^D 8D X‑D Laughing :D"), 4) Do $$$AssertEquals(##class(codeGolf.SmileyFace).Count("Sadness >:( :[ :{ :("), 0) } }
Comments
//Untested, just to get started.. about 127
Class codeGolf.SmileyFace Extends %RegisteredObject
{
ClassMethod Count(i As %String) As %Integer
{
f p=1:1:$l(i){i $e(i,p,*)?1(1":",1";",1"8",1"B",1"=").1(1"-",1"^",1"c",1"o",1"~")1(1")",1"]",1"}",1"D",1">").e,$i(c)} q $g(c)
}
}
Additional explanations are required.
It is not entirely clear from the description whether one smiling mouth is acceptable, for example ")", "D", etc., and also why "))" is a valid smiley face.
I have some Russian colleagues who use )) like a smiley face. I believe that it's more of a regional expression. Like here in Brazil, we use 'kkkkk' to represent laughter.
Regional preferences have nothing to do with it.
From the conditions of the task it is unclear how many mouths, noses and eyes are allowed in one emoticon (based on physiology one at a time (we do not count pathologies)): ")", "))", ")D", ")))", "xD", "xDD"
Edited description.
- Mouths: 1
- Noses: 0-1
- Eyes: 0-1
In addition, test case 1 & 5 & 9 have been modified/edited.
In the past we got challenges with a better definition... ;-(( ☹
In the original post, I'm pretty sure, there were
")s)).:D :~) ;~D :) xD ))" instead of
")s).:D :~) ;~D :) xD"
and
"(smiley) ))" instead of
"(smiley)"
Nevertheless,
"Sadness >:( :[ :{ :(" ---> you say: 0
> I say: 1 (0 Eyses, 0 noses 1 mouth)
and there is no rule about interspace requirementsMy quick solution:
ClassMethod Count(s)
{
while$locate(s,"[:;8B=]?[co\^~-]?[\)\]\}D>]",$g(i),i),$i(n){} q +$g(n)
}
/// If one accepts "" as 0 then change +$g(n) to $g(n)/// I would like a solution as (see the + char in regex)/// but then the rules should be changed///ClassMethod Count(s)
{
while$locate(s,"[:;8B=]?[co\^~-]?[\)\]\}D>]+",$g(i),i),$i(n){} q +$g(n)
}Length: 77
Spoiler
ClassMethod Count(i As%String) As%Integer
{
s i=$tr(i,":;8B=-^co~","") f p=1:1:$l(i){i ")]}D>"[$e(i,p),$i(c)} q +$g(c)
}"12 weirds ..." test case failed.
Length 50
Spoiler
ClassMethod Count(i As%String) As%Integer
{
f p=1:1:$l(i){i ")]}D>"[$e(i,p),$i(c)} q +$g(c)
}It seems the task definition lacks the preciseness and you have the power of observation. What about this?
ClassMethod Count(s)
{
q$l($tr(s,")]}>","DDDD"),"D")-1
}"Sadness..." test case failed.
ClassMethod Count(s)
{
q$l(s)-$l($tr(s,")]}D>"))
}while "Sadness..." test case fails as well. It seems that this case contradicts the specs as it contains ">" which is a valid "mouth".
Sadly, I haven't a shorher solution than yours but another one (with the same size)
ClassMethod Count(s)
{
q$l($tr(s,")]}D>"_s,1E4))
}That's really elegant!