25
\$\begingroup\$

Write a program that accepts as input an emoticon and ouputs if the emoticon is happy or sad.

The program accepts a string as input or parameter, and should display the string "happy" if the input is in the happy emoticon list, or "sad" if the input is in the sad emoticon list.

You can assume the input is always a valid (happy or sad) emoticon, with no space or tabs around.

Here is a space separated list of happy emoticons:

:-) :) :D :o) :] :3 :c) :> =] 8) =) :} :^) :-D 8-D 8D x-D xD X-D XD =-D =D =-3 =3 B^D (-: (: (o: [: <: [= (8 (= {: (^:

Here is a space separated list of sad emoticons:

>:[ :-( :( :-c :c :-< :< :-[ :[ :{ 8( 8-( ]:< )-: ): >-: >: ]-: ]: }: )8 )-8

This is code-golf, so the shortest program wins.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You forgot about :'D, :') (happy) and :@ (angry) \$\endgroup\$ Sep 13, 2015 at 0:11

13 Answers 13

20
\$\begingroup\$

Python, 86 bytes

I should be sent to prison.

x=lambda c: ["happy","sad"][c[0]+c[-1:]in open(__file__).read(88)[::-1]]#<][><:>{:}(:)

The shortest I could come up with was equivalent to Martin's CJam answer, so I decided I'd hide all the sad emojis (minus the middle character if any) in the reverse of my code and use Python's __file__ quine cheat.

Muahahaha.

\$\endgroup\$
5
  • \$\begingroup\$ Very well thought \$\endgroup\$
    – edc65
    Sep 12, 2015 at 15:56
  • \$\begingroup\$ Actually, now that I look at your code, will removing the space after the colon help anything, or will it just break the program? \$\endgroup\$
    – Beta Decay
    Sep 12, 2015 at 17:54
  • 6
    \$\begingroup\$ I love that the program contains its own emoticon: c: \$\endgroup\$
    – Alex A.
    Sep 12, 2015 at 22:31
  • \$\begingroup\$ @BetaDecay it'll break it heheh \$\endgroup\$
    – cjfaure
    Sep 13, 2015 at 19:10
  • 1
    \$\begingroup\$ @AlexA. it also has these, if you look carefully: 8) (8 :] [: \$\endgroup\$
    – cjfaure
    Sep 13, 2015 at 19:11
16
\$\begingroup\$

CJam, 33 32 bytes

Thanks to Dennis for saving 1 byte.

q)"[(c<{"&\"])>}"&|"sad""happy"?

Looks like it's shorter to do the same thing without a regex...

Test it here.

Explanation

This based on the same observation as the Retina answer, but this time matching happy faces doesn't have any benefit, so we'll match sad faces instead (because there's one less mouth to take into account). The solution is otherwise exactly the same, except that it's not implemented via regex substitution:

q)             e# Read input and split off last character.
"[(c<{"&       e# Set intersection with the sad right-hand mouths.
\              e# Pull up remaining emoticon.
"])>}"&        e# Set intersection with the sad left-hand mouths.
|              e# Set union, which amounts to a logical OR in this case.
"sad""happy"?  e# Pick the correct string.
\$\endgroup\$
1
  • 7
    \$\begingroup\$ Woah, give the rest of us a chance Martin :D \$\endgroup\$
    – Beta Decay
    Sep 12, 2015 at 10:31
10
\$\begingroup\$

Retina, 38 36 bytes

.+[])D3>}]|[<[({].+
happy
^...?$
sad

We can recognise all emoticons by their mouths, because none of the mouths is used as a hat or eyes in the other set (only in the same set). The happy ones have one more mouth to take into account, but they have the benefit that the mouths don't appear in the other set at all, not even as noses (the opposite is not true: c is both a sad mouth and a happy nose). This means we can avoid using anchors but instead just ensure that there are more characters on the other side of the mouth.

So the valid mouths for happy faces are ] ) D 3 > } on the right or < [ ( { on the left. We match those with .+[])D3>}]|[<[({].+ and replace them with happy. If we didn't match there will be two or three characters in the string (the emoticon), but if we did there will be five (happy). So in a second step we replace two or three characters with sad.

\$\endgroup\$
2
  • \$\begingroup\$ We can recognise all emoticons by their mouths, because none of the mouths is used as a hat. Well, the ]:< emoticon uses a mouth as a hat, just saying. \$\endgroup\$
    – xenia
    Sep 12, 2015 at 10:47
  • \$\begingroup\$ @Loovjo except there is no . after "hat" in my answer. ;) "... as a hat or eyes in the other set (only in the same set)." \$\endgroup\$ Sep 12, 2015 at 10:50
8
\$\begingroup\$

JavaScript (ES6), 46

Using a regexp to find sad emoticons, that are those beginning with >)]} or ending with <([{c. Side note: other regexps here may be shorter but I'm not sure to understand them.

Usual note: test running the snippet on any EcmaScript 6 compliant browser (notably not newest Chrome but not MSIE. I tested on Firefox, Safari 9 could go)

Big news It seems arrow functions finally arrived to Chrome land! Rel 45, august 2015

F=s=>/^[\])}>]|[[({<c]$/.test(s)?'sad':'happy'

//Same length
X=s=>/[\])}>].|.[[({<c]/.test(s)?'sad':'happy'

Y=s=>s.match`].|[)}>].|.[[({<c]`?'sad':'happy'
                 
//TEST
out=x=>O.innerHTML+=x+'\n';

sad='>:[ :-( :( :-c :c :-< :< :-[ :[ :{ 8( 8-( ]:< )-: ): >-: >: ]-: ]: }: )8 )-8'.split` `
happy=':-) :) :D :o) :] :3 :c) :> =] 8) =) :} :^) :-D 8-D 8D x-D xD X-D XD =-D =D =-3 =3 B^D (-: (: (o: [: <: [= (8 (= {: (^:'.split` ` 

out('The sad faces')                   
sad.forEach(x=>out(x + ' is ' + F(x)))
out('\nThe happy faces')
happy.forEach(x=>out(x + ' is ' + F(x)))
<pre id=O></pre>

\$\endgroup\$
2
  • \$\begingroup\$ works great on chrome \$\endgroup\$
    – Glycerine
    Sep 12, 2015 at 13:39
  • 3
    \$\begingroup\$ @Glycerine so now Chrome recognize => ? I missed that news \$\endgroup\$
    – edc65
    Sep 12, 2015 at 13:45
4
\$\begingroup\$

Julia, 87 69 bytes - saved 18 bytes thanks to Alex A.

s=readline();print(s[end-1] in")D]3>}"||s[1] in"([<{"?"happy":"sad")
\$\endgroup\$
1
  • 2
    \$\begingroup\$ You can save a bunch by using a ternary instead of the if/else and putting the ternary inside of print to avoid having to assign t. \$\endgroup\$
    – Alex A.
    Sep 12, 2015 at 16:52
4
\$\begingroup\$

Python 3, 77 75 74 72 61 55 bytes

lambda e:('happy','sad')[e[-1]in'[(c<{'or e[0]in'])>}']

Try it online!

How does it work

If a face string starts with ])>} or ends with [(c<{, it is sad, otherwise it is happy. Tuple indexing is used as if.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Welcome to Programming Puzzles & Code Golf! \$\endgroup\$
    – Dennis
    Sep 14, 2015 at 22:30
  • \$\begingroup\$ Using a function is perfectly fine. In contrast, assuming the input is already stored in x is not allowed. \$\endgroup\$
    – Dennis
    Mar 24, 2018 at 15:34
3
\$\begingroup\$

Brachylog, 50 bytes

(rh{,"[(c<{":Im?};?h{,"])>}":Im?}),"sad".;"happy".

Explanation

(                              ),"sad".;"happy".  § If what's in the parentheses is true,
                                                  § output "sad", else output "happy".

 rhA                                              § Unify A with the last char of the input
    ,"[(c<{":ImA                                  § True if A is a char of "[(c<{"
                ;                                 § OR
                 ?hA                              § Unify A with the first char of the input
                    ,"])>}":ImA                   § True if A is a char of "])>}"
\$\endgroup\$
2
\$\begingroup\$

Python, 159 bytes.

i,e=raw_input(),0
for c in i:e=(e,i.index(c))[c in":=8xXB"]
f,s,h=i[:e],i[e+1:],0
for c in f:h+=c in"[(c<{"
for c in s:h+=c in")]}>D"
print["Sad","Happy"][h>0]
\$\endgroup\$
2
\$\begingroup\$

MATLAB, 85 83 bytes

There must be a way to reduce the size here.

e=input('');if any([e(end)=='[(c<{',e(1)=='])>}']),'sad';else 'happy';end,disp(ans)

Input is a smiley string. First and last characters will be compared to determine whether it's sad. If not, it's happy.

I was able to save 2 bytes by not displaying either, but assigning them to MATLAB's default variable (ans) instead and then displaying ans after the if-statement. But I'm convinced it can be improved somehow.

2 bytes improvement by changing function s(e), to e=input('');.

\$\endgroup\$
1
\$\begingroup\$

PowerShell, 92 Bytes

param([char[]]$a)if("<[({".IndexOf($a[0])+"})D3]>".IndexOf($a[-1])-eq-2){"sad"}else{"happy"}

A little wordy, but as a bonus, it doesn't use regex!

This takes advantage of the .NET <string>.IndexOf() function that returns -1 if the character isn't found in the string. So, if the first character isn't a "happy" character, the first IndexOf() will be -1 -- likewise for the last character. So, if it's a sad face, the IndexOf()s will always sum to -2, meaning the -eq-2 is $TRUE, and thus sad gets printed.


Bonus variant: PowerShell with Regex, 95 bytes

param([char[]]$a)if(($a[0]-match"[<\[\(\{]")-or($a[-1]-match"[\}\)D3\]>]")){"happy"}else{"sad"}
\$\endgroup\$
1
\$\begingroup\$

Python 3, 75 bytes

lambda y:"sad"if re.match("(.*[[(c<{]$)|(^[\])>}])",y)else"happy"
import re

Try it online

The regex import makes it a bit too long, as well as the inability to use None as an array index. But I like regex :)

\$\endgroup\$
1
\$\begingroup\$

Java 8, 52 bytes

e->e.matches(".+[\\[(c<{]|[)>\\]}].+")?"sad":"happy"

Try it online.

Explanation:

e->          // Method with String as both parameter return-type
  e.matches( ".+[\\[(c<{]|[)>\\]}].+")                   
             //  Checks if the input matches the regex
   ?"sad"    //  If it does: output "sad"
   :"happy"  //  Else: output "happy"

Java's String#matches implicitly adds ^...$ to match the entire String, which is why it is shorter to check for sad faces instead of checking for happy faces like most other answers do with .+[\\])D3>}]|[<\\[({].+ (because my regex would fail in @MartinEnder's Retina answer for example, due to the happy test case :c)).

Regex explanation:

^.+[\\[(c<{]|[)>\\]}].+$
^                           Start of the string
 .+                          One or more characters,
   [\\[(c<{]                 followed by one of "[(c<{"
            |               Or
             [)>\\]}]        One of ")>]}",
                     .+      followed by one or more characters
                       $    End of the string
\$\endgroup\$
1
\$\begingroup\$

[AutoHotkey], 78 bytes

InputBox,e
MsgBox % RegExMatch(e,"(^[\])>}].+$)|(^.+[\[(c<{]$)")?"sad":"happy"

How does it work

Using RegEx and ternary operator. Nothing new, as some answers used this method too. If input string starts with ])>} or ends with [(c<{, it is sad, otherwise it is happy.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.