30
\$\begingroup\$

In this challenge, submissions will be programs or function which, when given an emoticon such as :-), :(, or :D, will rate their happiness from 0 to 3.

An emoticon will be one of the following:

  • :(: 0
  • :|: 1
  • :): 2
  • :D: 3

Emoticons may also have noses (a - after the :).

Test cases:

:(  -> 0
:-| -> 1
:D  -> 3
:-) -> 2
:|  -> 1

This is a code golf challenge, shortest answer per language wins.

\$\endgroup\$
  • 9
    \$\begingroup\$ What about (:? \$\endgroup\$ – anatolyg Apr 2 at 13:06
  • \$\begingroup\$ @anatolyg I figured having to handle reversed strings as well would make the challenge too difficult \$\endgroup\$ – Redwolf Programs Apr 2 at 15:34
  • \$\begingroup\$ @anatolyg Don't forget ☺and ☻ either \$\endgroup\$ – Chronocidal Apr 2 at 16:20
  • 2
    \$\begingroup\$ @anatolyg What about D:? \$\endgroup\$ – Λ̸̸ Apr 3 at 8:59

35 Answers 35

14
\$\begingroup\$

Python 3, 26 bytes

lambda s:ord(s[-1])*2%19%4

Try it online!

$$ f(x) = (2x \bmod 19) \bmod 4 $$

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You can save 1 character by using the formula in the Ruby solution below : codegolf.stackexchange.com/a/202907/61997 \$\endgroup\$ – mr.mams Apr 3 at 10:41
  • \$\begingroup\$ @mr.mams, then it will be absolutely identical to another python answer \$\endgroup\$ – Dion Apr 5 at 7:40
11
\$\begingroup\$

APL (Dyalog), 11 8 bytes

3 bytes saved thanks to @Bubbler!

⊃'(|)'⍳⌽

Try it online!

       ⌽  reverse the string
⊃         take the last (now first) byte
 '(|)'⍳    index inside '(|)' (if not found ('D') returns the length (3))
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ 8 bytes \$\endgroup\$ – Bubbler Apr 2 at 1:47
  • \$\begingroup\$ @Bubbler Unfortunately, it says the link can’t be decode; mind repasting? \$\endgroup\$ – Avi F. S. Apr 2 at 3:02
  • \$\begingroup\$ @AviF.S. Here it is. Weird though, because I can open it fine on my PC. \$\endgroup\$ – Bubbler Apr 2 at 3:22
  • \$\begingroup\$ Very odd! Still doesn’t work for me but I’m on the mobile app (iPhone). Though I couldn’t find anything on Meta re: bugs with TIO and mobile... Suppose I’ll just hold my excitement ‘til I can check on my computer :) \$\endgroup\$ – Avi F. S. Apr 2 at 3:33
  • \$\begingroup\$ thanks @Bubbler \$\endgroup\$ – Uriel Apr 2 at 8:48
10
\$\begingroup\$

Ruby, 20 bytes

s[-1].ord will give us the codepoint of the last character in the string, which we can then plug into this formula: $$(160 \bmod c) \bmod 7 $$

->s{160%s[-1].ord%7}

Try it online!

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ Nice find on the formula! I tried brute-forcing for expressions in Python no longer than 160%n%7 (7 bytes) and got only that with nothing shorter. Here are the 8-byte ones: TIO \$\endgroup\$ – xnor Apr 2 at 3:14
7
\$\begingroup\$

Python 3, 28 27 bytes

lambda e:"(|)D".find(e[-1])

Try it online!

Because we don't care about the eyes/nose, we can just look at the mouth (the last character) and find its index in a string with all the mouths, ordered from saddest to happiest :) Thanks @Surculose Sputum!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ find works the same as index and saves 1 byte \$\endgroup\$ – Surculose Sputum Apr 1 at 16:42
6
\$\begingroup\$

Python 3, 25 bytes

lambda s:160%ord(s[-1])%7

Try it online!

Math taken from @dingledooper

| improve this answer | |
\$\endgroup\$
4
\$\begingroup\$

C (gcc),  37  33 bytes

Saved 4 bytes on both versions thanks to @ceilingcat and @dingledooper

I overlooked the rule about the optional nose, so this is not as effective as expected.

f(char*s){s=390%~-s[*++s%9<1]&3;}

Try it online!

How?

Among the characters that we have to deal with, the hyphen is the only one whose ASCII code is congruent to \$0\$ modulo \$9\$. We use this property to decide whether we need to work on the second or the third character.

Given the ASCII code \$n\$ of the relevant smiley character, we apply the following formula to get the happiness:

$$h(n)=(390\bmod (n-1))\bmod 4$$


C (gcc),  36  32 bytes

Using Uriel's formula is 1 byte shorter.

f(char*s){s=s[*++s%9<1]*2%19&3;}

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ -1 byte for both, by recursively searching for the end of the string. \$\endgroup\$ – Bubbler Apr 2 at 1:43
3
\$\begingroup\$

Jelly,  8  7 bytes

⁽$9,4ḥ’

A monadic Link accepting a list of characters which yields an integer in \$[0,3]\$.

Try it online!

How?

⁽$9,4ḥ’ - Link: list of characters, A
⁽$9     - base 250 literal = 10058
   ,4   - pair with four
     ḥ  - Jelly hash A using 10058 as a salt and [1,2,3,4] as the domain
      ’ - decrement

Previous 8 byter:

“|)D”iⱮS

Try it online!

How?

“|)D”iⱮS - Link: list of characters, A             e.g. ":-)"     OR  ":-("
      Ɱ  - map across c in A with:
     i   -   first index of c in (or 0 if not found):
“|)D”    -     list of characters = "|)D"               [0,0,2]       [0,0,0]
       S - sum                                          2             0
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Keg, -hr, 18 bytes

?^⑵¦P0|\🄃1|R2|\¦3™

Try it online!

The same switch statement format, but with a different character checking criteria.

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Bash + GNU utilities, 17 bytes

tr '(|)D:-' 0-3\ 

Try it online!

Note: There's a space character after the backslash.

Input on stdin, output on stdout.

The challenge doesn't specify the format of the output. Depending on the input, this program may print the output in either %2d or %3d format (that is, with one or two spaces before the 0, 1, 2, or 3).

If that's not acceptable, then

tr -s '(|)D:-' 0-3\

(20 bytes) always prints the digit in %2d format. (There's a space after the backslash here too.)

Or

tr '(|)D:-' 0-4|tr -d 4

(23 bytes) prints just the digit (with no spaces).

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Retina 0.8.2, 16 12 bytes

T`-:(|)D`__d

Try it online!

T`

Enter transliteration mode

(|)D`d

Replace the mouth character with the corresponding digit (0 to 3)

-:`__

Remove each of - and : from the string.

Implicitly output the result, which will be a single digit.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

MATL, 9 bytes

'|)D'jmfs

Try it online!

Explanation

'|)D' % Push this string
j     % Read input as unevaluated string
m     % ismember: true for chars of the first string that are present in the second
f     % find: (1-based) indices of true entries. The result will have length 0 or 1
s     % sum. This is needed to transform an empty array into 0
      % Implicitly display
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Raku, 19 bytes

{TR:d/(|)D:-/0123/}

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ If raku -p is acceptable, you could reduce to tr:d/(|)D:-/0123/ \$\endgroup\$ – Sebastian Apr 4 at 4:18
2
\$\begingroup\$

naz, 120 bytes

8a5m2x1v1a2x2v4a2x3v9a9a5a2x4v1x1f2r3x3v1e2f0x1x2f3x1v3e3x2v5e3x4v6e4f0x1x3f0m1o0x1x4f0m1a1o0x1x5f0m2a1o0x1x6f0m3a1o0x1f

Explanation (with 0x commands removed)

8a5m2x1v                 # Set variable 1 equal to 40 ("(")
1a2x2v                   # Set variable 2 equal to 41 (")")
4a2x3v                   # Set variable 3 equal to 45 ("-")
9a9a5a2x4v               # Set variable 4 equal to 68 ("D")
1x1f                     # Function 1
    2r                   # Read the second byte in the input string, removing it
      3x3v1e             # Jump back to the start of the function if it equals variable 3
            2f           # Otherwise, jump to function 2
1x2f                     # Function 2
    3x1v3e               # Jump to function 3 if the register equals variable 1
          3x2v5e         # Jump to function 5 if the register equals variable 2
                3x4v6e   # Jump to function 6 if the register equals variable 4
                      4f # Otherwise, jump to function 4
1x3f                     # Function 3
    0m1o                 # Output 0
1x4f                     # Function 4
    0m1a1o               # Output 1
1x5f                     # Function 5
    0m2a1o               # Output 2
1x6f                     # Function 6
    0m3a1o               # Output 3
1f                       # Call function 1
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 8 bytes

θÇx19%4%

Try it online!

Explanation

I used Uriel's formula.

θ        # Get mouth (last char)
 Ç       # ASCII value
  x      # Multiply by 2
   19%   # Modulo 19
      4% # Modulo 4
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ If you don't want to have the answer wrapped into a list, you could swap the θÇ to Çθ. (PS: x actually pushes 2n without popping, but there is also · which pops and pushes 2n. Doesn't matter here, but figured I'd let you know in case you're using it in future answers.) Here also another 8-bytes alternative based on dingledooper's Ruby answer: ƵxIÇθ%7%. Try it online. \$\endgroup\$ – Kevin Cruijssen Apr 2 at 10:10
  • 1
    \$\begingroup\$ @Kevin Cruijssen I knew that x did that, just that I looked for * 2 and not 2 * in info.txt. I also made a solution based on dingledooper's formula, but it was 9 bytes. \$\endgroup\$ – PkmnQ Apr 2 at 10:14
2
\$\begingroup\$

Excel, 25 bytes

=FIND(RIGHT(A1),"(|)D")-1
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

batch, 109 Bytes

@for %%A in ("(=0","|=1",")=2","D=3") do @Set %%A
@Set "T=%~1"
@Set "O=%T:~1,1%"
@Call Call Echo("%%%O%%%"

output (TIO unavailable)

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ 106 Bytes when lines are terminated by LF instead of CR LF, using Shift+CTRL+J \$\endgroup\$ – T3RR0R Apr 2 at 16:24
  • 1
    \$\begingroup\$ the space in front of do is optional \$\endgroup\$ – HackingAddict1337 Apr 25 at 13:34
2
\$\begingroup\$

C# (Visual C# Interactive Compiler), 17 14 bytes

Turns out Ranges finally started to actually exist and work! Thanks to an anonymous user for pointing this out (by proposing an edit, but anonymous users cannot comment...)

s=>160%s[^1]%7

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -p, 24 bytes

s/.*(.)/ord($1)*2%19%4/e

Try it online!

Steals the math from @Uriel's Python answer

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 10 bytes

I⌕(|)D§S±¹

Try it online! Link is to verbose version of code. Explanation:

       S    Input string
      §     Cyclically indexed by
         ¹  Literal 1
        ±   Negated
 ⌕          Find index in
  (|)D      Literal string of mouths
I           Cast to string
            Implicitly print
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Io, 31 bytes

Io's strings are made of integers, so character-converting is unneccecary. Although Io doesn't allow us to index the last item of a sequence using last()...

method(x,160%x reverse at(0)%7)

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Red, 32 bytes

func[s][select"(0|1)2D3"last s]

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

J, 10 9 bytes

-1 byte thanks to FrownyFrog ang Bubbler

'(|)'i.{:

Try it online!

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ You can drop D as bubbler pointed out. \$\endgroup\$ – FrownyFrog Apr 3 at 19:34
  • \$\begingroup\$ @FrownyFrog Yes, indeed. Thanks! \$\endgroup\$ – Galen Ivanov Apr 3 at 20:35
1
\$\begingroup\$

PowerShell, 16 bytes

2*$args[-1]%19%4

Try it online!

PowerShell port of the modulo formula going around. Takes input via splatting

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Pyth, 8 bytes

x"(|)D"e

Try it online!

Exalanation

x"(|)D"e
          : Implicit evaluated input
       e  : Last element of input
 "(|)D"   : The string "(|)D"
x         : First occurrence of the last element of input in "(|)D"
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Mornington Crescent, 1820 bytes

Try it online!

A port of @dingledooper's fantastic Ruby answer, which just so happens to work seamlessly in Mornington Crescent because of a convenient 7 in it. Props to them!

Take Northern Line to Leicester Square
Take Northern Line to Leicester Square
Take Piccadilly Line to Turnpike Lane
Take Piccadilly Line to Turnpike Lane
Take Piccadilly Line to Leicester Square
Take Northern Line to Leicester Square
Take Northern Line to Charing Cross
Take Northern Line to Charing Cross
Take Bakerloo Line to Baker Street
Take Bakerloo Line to Paddington
Take Bakerloo Line to Charing Cross
Take Bakerloo Line to Charing Cross
Take Northern Line to Moorgate
Take Circle Line to Moorgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to King's Cross St. Pancras
Take Victoria Line to Seven Sisters
Take Victoria Line to Victoria
Take Circle Line to Victoria
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Hammersmith
Take Circle Line to Cannon Street
Take Circle Line to Bank
Take Circle Line to Hammersmith
Take District Line to Upminster
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Victoria
Take Circle Line to Victoria
Take Circle Line to Aldgate
Take Circle Line to Aldgate
Take Metropolitan Line to Chalfont & Latimer
Take Metropolitan Line to Preston Road
Take Metropolitan Line to Baker Street
Take Metropolitan Line to Preston Road
Take Metropolitan Line to Pinner
Take Metropolitan Line to Preston Road
Take Metropolitan Line to King's Cross St. Pancras
Take Victoria Line to Seven Sisters
Take Victoria Line to King's Cross St. Pancras
Take Circle Line to King's Cross St. Pancras
Take Metropolitan Line to Pinner
Take Metropolitan Line to Preston Road
Take Metropolitan Line to Pinner
Take Metropolitan Line to Preston Road
Take Metropolitan Line to King's Cross St. Pancras
Take Circle Line to King's Cross St. Pancras
Take Northern Line to Mornington Crescent

The only major thing I feel I need to point out is how I got 160 in the program. To do this, I took the first letter of Paddington, which gives an ASCII value of 80 when run through Charing Cross, then multiplied it by 2 in Chalfont & Latimer to get 160. Subsequently, the program computes 160 % (ASCII of last character) % 7 via Preston Road, the formula found by @dingledooper.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Japt, 9 bytes

"(|)D"bUÌ

Try it

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Erlang (escript), 32 bytes

The verbosity offseted the bytecount.

h(I)->160rem lists:last(I)rem 7.

Try it online!

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

W, 7 bytes

☻M:ù·±♥

Uncompressed:

(|)D"azx

Explanation

         % Implicit quote
(|)D"    % The string "(|)D"
     az  % The last item of the input
       x % Where is ^ in the above string?
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Kotlin, 27 24 bytes

-3 Refactor to remove it.

{"(|)D".indexOf(last())}

Try it online!

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

T-SQL, 34 bytes

SELECT CHARINDEX(RIGHT(@,1),'|)D')-1

Requires the variable @ to be declared and assigned the input.

This code takes the right most character, and searches an indexed list of the possible mouthes. CHARINDEX returns a 1-based index. But, failing to find anything returns 0. So we leave the frown out of the search string (making the sad face even sadder).

Try it online! (SQL Fiddle)

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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