Your task is to generate an emoticon of three characters, the first character being one eye, the second the mouth, and the third another eye. Each eye is a random one of these characters: $'*+-;O^`ox~, and the mouth is a random one of these: ,-._coux.

Each eye and the mouth must be on the same general level. These eyes: '*;^` and these mouths: -coux are "upper-level", while these eyes: $+-Oox~ and these mouths: ,._ are "lower-level". Any emoticon has a 50 % chance of using only upper-level eyes and mouth, and a 50 % chance of using only lower-level ones.

Additionally, the eyes should usually not be different. The chance of the eyes using the same symbol must be somewhere between 50 % and 67 %.


  • The submission must be a function or a full program.
  • The submission must either print the emoticon to the screen with optional trailing and/or preceding whitespace, or returning the emoticon as a string.
  • The emoticon should have a 50 % chance of being upper-level and a 50 % chance of being lower-level.
  • All eyes and mouths of the same level must have the same chance of occuring.
  • The eyes should be the same 50-67 % of the time.
  • Standard loopholes apply.
  • This is a , so the shortest answer in bytes wins!


-_-     // All symbols are lower-level: valid
~o.~    // Two eyes on the left side: invalid
^^      // No mouth - invalid
^_^     // The mouth is lower-level but the eyes are not: invalid
^-*     // All symbols are upper-level: valid
---     // Eyes are lower-level but mouth is upper-level: invalid


  • 3
    \$\begingroup\$ Suggest example --- invalid \$\endgroup\$
    – l4m2
    Commented Feb 11, 2023 at 11:42

13 Answers 13


Japt -P, 43 bytes

"'*;^` -coux $+-Oox~ ,._"¸ò ö
Vp[VU]ö Îö

Saved four thanks to Shaggy

Try it or generate 10 emoticons

"'*;^` -coux $+-Oox~ ,._"¸ò ö : Implicit input
"'*;^` -coux $+-Oox~ ,._"     : Each part, separated by spaces
                         ¸    : Split on spaces
                          ò ö : Random pair; store in U
mö : Map each element of U to a random character of that string
   : The result is [random eye, random mouth]; store in V
Vp[VU]ö Îö
Vp         : Append to V:
  [VU]ö    :   Random element of the tuple [V, U]
        Î  :   First element, either first eye or all eyes
         ö :   Random character
           : -P joins this array to a string
  • 3
    \$\begingroup\$ Why did this get downvoted? It's a valid answer as far as I can tell \$\endgroup\$ Commented Feb 11, 2023 at 14:16
  • 2
    \$\begingroup\$ 43 bytes. But I think we can do better, still. \$\endgroup\$
    – Shaggy
    Commented Feb 13, 2023 at 8:22
  • \$\begingroup\$ @Shaggy I haven't found anything yet but I bet it can get rid of the final ö somehow \$\endgroup\$ Commented Feb 14, 2023 at 1:48

Vyxal, 45 39 36 bytes

- 6 bytes yeah lyxal outgolfed me in about 2 5 minutes
- 3 bytes by AndrovT using an amazing approach

`-⇩Ḋx '*;^\`,._ $+-Oox~`½℅⌈÷2ƈṅ2ƈ$℅Y

Try it Online!

How it works

`-⇩Ḋx '*;^\`,._ $+-Oox~`½℅⌈÷2ƈṅ2ƈ$℅Y

`-⇩Ḋx '*;^\`,._ $+-Oox~`½℅⌈    Compressing part:
`-⇩Ḋx '*;^\`,._ $+-Oox~`        Slightly compressed string "-coux '*;^`,._ $+-Oox~"
                        ½℅      Get random half of string (upper and lower level)
                          ⌈     Split on space (eyes and mouth)

÷2ƈṅ2ƈ$℅Y    Random part:
÷             Dump list on register
 2ƈṅ          Choose two random eyes and concatenate them
    2ƈ        Again, choose two random eyes from the above string (probability of having same eyes: 7/12)
       $℅     Swap and choose random mouth
         Y    Interleave eyes with mouth
  • 1
    \$\begingroup\$ 5 minutes. It was 5 minutes :p \$\endgroup\$
    – lyxal
    Commented Feb 11, 2023 at 13:33

05AB1E, 46 45 43 39 38 bytes

"-coux '*;^`,._ $+-Oox~"2äΩ#`©âΩ¤®Ω‚Ωì

-1 byte by taking inspiration of @mathcat's Vyxal answer regarding the split on space in the string.
-4 bytes taking inspiration of @Jacob's Japt answer regarding the 'random element of the tuple [first eye, random eye]'.

Try it online or output a given input amount of random outputs.


Code explanation:

"-coux '*;^`,._ $+-Oox~" # Push this string
 2ä                      # Split it into 2 equal-sized parts:
                         #  ["-coux '*;^`",",._ $+-Oox~"]
   Ω                     # Pop and push a random string of the two
    #                    # Split it on the space
     `                   # Pop and push the strings in the current pair separately to
                         # the stack
      ©                  # Store the top string (the eyes) in variable `®` (without
                         # popping) 
       â                 # Get all possible pairs with the cartesian product of the two
        Ω                # Pop and push a random partial emoticon from this list
         ¤               # Push the last character (the eye) (without popping)
          ®              # Push the eyes-string of variable `®` again
           Ω             # Pop and push a random eye from this string
            ‚            # Pair the first eye and random eye together
             Ω           # Pop and push a random eye from this pair
              ì          # Prepend it to the partial emoticon to complete it
                         # (after which it is output implicitly as result)

Minor note: compressing "-coux '*;^`,._ $+-Oox~" as a list of codepoint integers we then convert to ASCII characters would be 3 bytes longer than the literal string with •1Γ∞™årÒCиÐ}‡δíl|“"5Ì•ƵQвçJ.

Percentages explanation:

  • The 50%/50% for either upper-/lower-level emoticons is done by the first Ω after we've split the string into two parts with .
  • The 50-67% of the same eyes in comparison to different eyes is 50%/50% as well, with the last Ω just before the ¬®нΩ‚, which pairs the first eye with a random eye together.

Python, 125 bytes

from random import*

Attempt This Online! or generate 10 emoticons

The eyes are the same if they are upper level (50% of the time) or if the choice function selects the same eye again (less than 17% so we don't have to worry about that).


Thunno K, \$ 58 \log_{256}(96) \approx \$ 47.74 bytes

"'*;^` -coux$+-Oox~ ,._"2APZwA_ZiAusDZwsZw+DZwsZw+sZwsAuZs

Attempt This Online! or generate 10 emoticons.

Port of mathcat's Vyxal answer.

Outputs a list of characters. Add the J flag if you want a single string.


"..."           # Push the string
     2AP        # Split it in half
        Zw      # Get a random half
          A_Zi  # Split on the space

Aus                        # Dump onto the stack and swap
   DZwsZw+                 # Get two random items from the eyes:
   D                       #  Duplicate
    Zw                     #  Get a random item
      s                    #  Swap
       Zw                  #  Get another random item
         +                 #  Concatenate
          DZwsZw+          # Get two random items from this string:
           Zw              #  Get a random item
             s             #  Swap
              Zw           #  Get another random item
                +          #  Concatenate
                 sZw       # Swap and get a random item from the mouths
                    sAu    # Swap and dump onto the stack
                       Zs  # Swap the second and third items on the stack
                           # The K flag pushes the stack, which is output implicitly
  • \$\begingroup\$ The pages of code you've linked to doesn't seem to always print eyes and mouths in the right order. Most of the time, they print eye-mouth-eye, but sometimes they print eye-eye-mouth or mouth-eye-eye. \$\endgroup\$
    – Peter
    Commented Feb 12, 2023 at 8:49
  • \$\begingroup\$ Sorry, I accidentally changed something which led to the bug. Does it work now? \$\endgroup\$
    – The Thonnu
    Commented Feb 12, 2023 at 8:54
  • \$\begingroup\$ Now it sometimes prints eye-mouth-eye and sometimes mouth-eye-mouth. \$\endgroup\$
    – Peter
    Commented Feb 12, 2023 at 13:53
  • \$\begingroup\$ Can you give an example of when that happens? I can't see it when I run it. \$\endgroup\$
    – The Thonnu
    Commented Feb 12, 2023 at 14:14
  • 1
    \$\begingroup\$ Yes, it works perfectly! And you reduced the byte count too, great job :) \$\endgroup\$
    – Peter
    Commented Feb 12, 2023 at 14:59

Factor + pair-rocket, 102 bytes

[ { "'*;^`"=> "-coux""$+-Oox~"=> ",._"} random
last2 over [ random ] tri@ .5 [ . over ] whenp 3array ]

Try it online!

An anonymous function that returns an emoticon when called.

  • { "'*;^`"=> "-coux""$+-Oox~"=> ",._"} A shorter way to write
{ { "'*;^`" "-coux" } { "$+-Oox~" ",._" } }
  • random Pick the high set or the low set at random
  • last2 over Place two copies of the eyes on the stack and one copy of the mouths
  • [ random ] tri@ Get a random character from each
  • .5 [ . over ] whenp 50 + ~8% chance of ditching the random right eye and replacing it with a copy of the left
  • 3array Combine the three characters into a string

JavaScript (Node.js), 108 107 105bytes


Try it online!


Charcoal, 44 bytes

≔⪪‽⪪“V2+⌊>"f↶8)D⦄∕9₂↔≡7¿”¹¹ θ≔E²‽⌊θη⪫E²‽η‽⌈θ

Try it online! Link is to verbose version of code. Explanation: Port of @mathcat's Vyxal answer.

≔⪪‽⪪“V2+⌊>"f↶8)D⦄∕9₂↔≡7¿”¹¹ θ

Split the string '*;^` -coux$+-Oox~ ,._ into two pieces of length 11, pick one at random, and split it on space. The first element of the resulting list is the eyes and the second is the mouths, but more interestingly, the elements are sorted, so we can use Minimum and Maximum to refer to them.


Pick two eyes at random.


Pick two eyes at random from the two eyes (this gives a slightly greater than 50% chance of two identical eyes since the original two eyes might have been the same anyway) and join them with a random mouth.


Retina, 60 bytes


Try it online! Explanation:


Insert the literal string '*;^`¶-coux$+-Oox~¶,._. This is shorter than using a Replace stage because *s and $s don't need to be quoted here.


Pick a set of eyes and mouths at random.


Separately shuffle the eyes and mouths.


Output the last eye, the first mouth, and then a random eye from the last two (giving an exactly 50% chance of a pair of identical eyes).


Japt -P, 43 41 39 bytes

"'$*+;-^O`o x-~c o,u.x_"ó ö ¸ê ÇpçZöÃmö

Test it

"..."ó ö ¸ê ÇpçZöÃmö
"..."                    :String Literal
     ó                   :Uninterleave
       ö                 :Random element
         ¸               :Split on spaces
          ê              :Palindromise
            Ç            :Modify last element, Z
             p           :  Append
              ç          :    Repeat to the same length
               Zö        :    Random character of Z
                 Ã       :End modify
                  m      :Map
                   ö     :  Random character
                         :Implicitly join & output

Scala, 414 bytes

Modified from @l4m2's Javascript answer.

\$ \color{red}{\text{The scala code outputs invalid emoticons at times. Any help would be appreciated.}} \$

\$ \text{414 bytes, It can be golfed much more.} \$

Golfed version. Try it online!

import scala.util.Random

object Main {
  def main(args: Array[String]): Unit = {
    val r = Random.nextFloat() > 0.5
    val a = Seq("*", ";", "^", "`")(Random.nextInt(4))
    val b = Seq(Seq("-", "c", "o", "u", "x"), Seq("$", "+", "-", "O", "o", "x", "~"))(if (r) 0 else 1)(Random.nextInt(if (r) 5 else 7))
    val c = Seq(a, Seq(",", ".", "_")(Random.nextInt(3)))(if (r) 0 else 1)

Ungolfed version. Try it online!

import scala.util.Random

object Main {

  def choice(seq: Seq[String]): String = {
    val random = new Random
    val index = random.nextInt(seq.length)

  def main(args: Array[String]): Unit = {
    val symbols = Seq("*", ";", "^", "`")
    val letters = Seq("-", "c", "o", "u", "x")
    val operators = Seq("$", "+", "-", "O", "o", "x", "~")
    val punctuations = Seq(",", ".", "_")

    val r: Boolean = Random.nextFloat() > 0.5

    val (a, b, c) = if (r) {
      val a = choice(symbols)
      val b = choice(letters)
      (a, b, a)
    } else {
      val a = choice(symbols)
      val b = choice(operators)
      val c = choice(punctuations)
      (a, b, c)

  • \$\begingroup\$ Thanks for answering :) Your program seems to output invalid emoticons at times, though (such as ^$_). \$\endgroup\$
    – Peter
    Commented Jun 6, 2023 at 19:28

Uiua, 59 56 bytes


Try it

I'm not convinced this as short as it gets but I haven't thought of anything better.



Randomly put one of the [eyes, mouths] pairs on the stack, with the eyes part at both the start and end.


Take a random character of each.


Remove the first character from the rest.


Pair this with the last character and pick one of them randomly.

Prepend this character back to the face.


Python 3, 120 bytes

Golfed version. Try it online!

from random import choice as c
print(l+c(m)+(c(e)if c([0,1])else l))

Ungolfed version.

from random import choice

eyes_chars, mouth_chars = choice([("'*;^`", "-coux"),   # upper eyes, mouth
                                  ("$+-Oox~", ",._")])  # lower eyes, mouth
left_eye = choice(eyes_chars)
      + choice(mouth_chars)
      + (choice(eyes_chars) if choice([0, 1]) else left_eye))

We choose the upper vs. lower character set 50% of the time as required. We choose right_eye = left_eye in about 58% of cases: 50% we choose deterministically, the other 8% are due to accidental matching.


Your Answer

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

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