# Ascii smiley face challenge

I made this because, although we have a bunch of other questions involving smiley faces, there is nothing for just printing an ASCII smiley face with as little code as possible.

Anyway, print this exactly (Trailing spaces allowed):

        **********
******************
**********************
*******  ******  *******
************************
**************************
**************************
*****   **********   *****
*****   ********   *****
******            ******
**********************
******************
**********


This is code-golf, so fewest bytes wins. Yes, you have to use asterisks.

# Python 3, 97 bytes

The string has a leading and trailing unprintable with value 5.

for c in"wç¿ğŗŗĵý6çw":c=ord(c);s=c%8*'*'+c//8%7*' '+c//56*'*';print(f'{s+s[::-1]:^26}')


Try it online!

# APL+WIN, 57 bytes

m,⌽m←13 13⍴(¯17+⎕av⍳'hedibkagbca⊢ceaecdafhkdihe')/26⍴' *'


String used to index into atomic vector has been adjusted to allow for differences between APL+WIN and Dyalog

Try it online! Thanks to Dyalog Classic

# Java (JDK), 153 bytes

v->{var s=0;for(var c:"HJ!DR!BV!AGBFBG!AX!@Z!@Z!@ECJCE!AECICE!AFLF!BV!DR!HJ".getBytes())System.out.print("\n* ".split("")[c/64+(s^=c/64)].repeat(c%32));}


Try it online!

## Explanation

The idea is to have toggle, s, which will tell us when to print spaces or stars. The number of those spaces or spaces is defined by each character used in the long string. Any letter is their corresponding number (A=1, B=2, ...), @ actually is zero, and ! also means 1, but it's in a lower range than A to know when to go to the next line.

We can see the smiley as a sequence of [0,26] spaces followed by stars [1,26], possibly repeated. This makes sure that if we provide 2 chars, the first char represent the spaces and the second char represent the stars. This toggling is done using s^=1.

But it happens that I have to insert new lines in that sequence. A new character would then mess up with that s^=1, so I changed that to s^=c/64, meaning that only letters and @ actually trigger the toggle, while ! result in s^=0 which is a no-op.

s c s^(c/64) c/64+(s^(c/64)) Result
0 ! 0 0 \n
0 [@-Z] 1 2   (space)
1 ! 1 1 Never occurs
1 [@-Z] 0 1 *

After the character is selected (but kept as a string, not as a character), it is repeated c%32 times. It is to note that '!' % 32 = 33 % 32 = 1 and '@' % 32 = 64 % 32 = 0. Java's .repeat(0) will indeed result in the empty string ("").

# 05AB1E, 7268 42 bytes

•A9lΘRfÓβèε¢|Ïí"·тjêøèÂ§Äα9₃ê˜ì•… *
ÅвJº.c


Try it online.

Explanation:

•A9lΘRfÓβèε¢|Ïí"·тjêøèÂ§Äα9₃ê˜ì•
"# Push compressed integer 61833926632893543016875916488121666051545681457434856388592933517828315
… *\n        # Push string " *\n"
Åв      # Convert the integer to base-" *\n" (which means to convert it to base-3,
# and index them into the 3-char string)
J     # Join all characters together to a string
º    # Mirror each line
.c  # And centralize all lines
# (after which the result is output implicitly)


This is the result without the mirror and centralize. The code for this is generated with this 05AB1E ASCII-art tip.
See this 05AB1E tip of mine (section How to compress large integers?) to understand why •A9lΘRfÓβèε¢|Ïí"·тjêøèÂ§Äα9₃ê˜ì• is 61833926632893543016875916488121666051545681457434856388592933517828315.

# PHP, (all versions) 119106104 71 bytes

<?=gzinflate("SP€ -8àåBå#‹cŠBe ,˜ ¸J„]¸dˆ’Cq#Œ³I]JK À‰Ûg8Ã=Ü");

WARNING: this code contains many non-printable chars and a function that is disabled in most online code testers. It is either impossible to enter the correct code on the page or run the function. Here is the php file I uploaded to gitHub so that you can test:

Try it OFFline!

For info, it was generated by PHP's file_put_contents with the direct result of gzdeflate, no other manipulation required, the file is not manually edited with an Hex program, the only modification is deleting the last null byte of the generated zip string in notepad.

Thanks to @hanshenrik for the help trying to share this shortest version!

Longer version that can be tested online:

## PHP, (version < 8.0) 104 bytes

<?=gzinflate(base64_decode(U1CAAC044OVC5SOLY4pCZaAsmAq4SoQUFl24ZIiSQ3EjjAOzDkkSXUpLAQnAHYnbZzjDAj3cAA));


Online PHP function(s)

Simply encoded with gz, which is not available in TIO so I provided another site's link. (inspired by this answer after following @Neil's link "In Honor of Adam West")

EDIT: zip shortened by removing trailing spaces + finally it's only alphanumeric chars so I could remove the quotes (the warning would not show in the output in TIO like it does with Online PHP functions)

• it's possible to skip base64_decode and the base64 and insert the gzip binary directly in the source code using var_export() and HxD Hex Editor, but it's not possible using VSCode; here is the base64 of a version of your code in only 83 bytes, but warning, this code is NOT VSCode-compatible, but it is php-compatible: PD89Z3ppbmZsYXRlKCdTUIAnLiJcMCIuJy044OVC5SOLY4pCZaAsmAq4SoQUFl24ZIiSQ3EjjAOzDkkSXUpLAQnAHYnbZzjDAj3cJy4iXDAiKTs= – hanshenrik Feb 2 at 19:56
• shaved off a few more bytes (more efficient NULL-encoding), now it's 72 bytes: PD89Z3ppbmZsYXRlKCdTUIAALTjg5ULlI4tjikJloCyYCrhKhBQWXbhkiJJDcSOMA7MOSRJdSksBCcAdidtnOMMCPdwAJyk7 – hanshenrik Feb 2 at 20:08
• (and i think its possible to shave off a few more bytes from the 72 solution with more efficient encoding of \\ but i haven't tried, not all \ needs to be escaped, just some of them =/ ) – hanshenrik Feb 2 at 20:24
• I get <br /> <b>Fatal error</b>: Uncaught Error: Undefined constant &quot;U1CAAC044OVC5SOLY4pCZaAsmAq4SoQUFl24ZIiSQ3EjjAOzDkkSXUpLAQnAHYnbZzjDAj3cAA&quot; in [...][...]:1 Stack trace: #0 {main} thrown in <b>[...][...]</b> on line <b>1</b><br />  when I run it. +2 bytes - I think the string needs quotes. – A username Feb 3 at 4:07
• @Ausername you have to run it on PHP version < 8.0, it used to throw a notice, then a warning from 7.2, and only became a fatal error with 8.0. I'll add the precision – Kaddath Feb 3 at 8:06

# Charcoal, 36 bytes

⭆”←＆∨n？Þ\W!π↖δ℅If#≕W⧴@b⪪¹λ”∨×Σι*ι‖Ｍ←


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

⭆”...”


Map over partially RLE-encoded string.

∨×Σι*ι


Replace non-zero digits with their count of *s.

‖Ｍ←


Reflect the result.

Out of interest, I tried porting my answer to In Honor of Adam West but that weighed in at a massive 39 bytes (although it was still my second best approach).

# 05AB1E, 33 bytes

Very similar to my Python answer, this encodes the half of every line as a 3-digit base 8 integer.

•Uмö€æ¤š∊η ø‘Kó•468вε8в„* Þ×J}º.c


Try it online!

Commented:

•Uмö€æ¤š∊η ø‘Kó•468в # compressed integer list
# [5,135,263,467,327,391,391,349,348,432,263,135,5] (base 10)
# [5,207,407,723,507,607,607,535,534,660,407,207,5] (base 8)

ε         }          # map over the integers; example: 467
8в                  # convert to base 8               [7, 2, 3]
…*                # push the string "* "
Þ             # create a infinite list by cycling the characters
×            # for each each base-8 digit, repeat the character at the same index this many times
#                                 ['*******', '  ', '***']
J           # join into a single string       '*******  ***'

º                    # mirror every line
.c                  # centralize and join by newlines

• •Uмö€æ¤š∊η ø‘Kó•468в can be •γÂÂàª[O‘ôγÌ¹‚5•₄;в for -1. And you've made a typo in your explanation: the … should be „. Nice approach btw! – Kevin Cruijssen Feb 2 at 20:30

# Perl 5, 93 bytes

say'IK
ES
CW
BHCGCH
BY
A[
A[
AFDKDF
BFDIDF
BGMG
CW
ES
IK'=~s/./('*',$")[--$|]x(-65+ord$&)/ger  Try it online! • Nice solution! If you use numbers for the number of spaces and A-Z for the number of asterisks you can save a few bytes more: Try it online! – Dom Hastings Feb 3 at 12:49 # JavaScript (ES6), 108 bytes _=>8a 4i 2m 172627 1o 0q 0q 053a35 153835 16c6 2m 4i 8a.replace(/./g,c=>"* "[_^=1].repeat(parseInt(c,36)))  Try it online! # JavaScript (ES6), 112 109 bytes Returns an array of strings. _=>[p=1020,960,768,515,512,0,0,28,526,519.9,768,960,p].map(n=>(g=(k,c="* "[n*8>>k&1])=>~k?c+g(k-1)+c:'')(12))  Try it online! ### How? Each value in the array represents the inverted 13-bit value of the left side of the smiley, divided by 8. Dividing by 8 saves 7 bytes overall, although there's a non-integer value in there (519.875, which can be rounded to 519.9). ........***** -> 1111111100000 -> 8160 / 8 = 1020 ....********* -> 1111000000000 -> 7680 / 8 = 960 ..*********** -> 1100000000000 -> 6144 / 8 = 768 .*******..*** -> 1000000011000 -> 4120 / 8 = 515 .************ -> 1000000000000 -> 4096 / 8 = 512 ************* -> 0000000000000 -> 0 / 8 = 0 ************* -> 0000000000000 -> 0 / 8 = 0 *****...***** -> 0000011100000 -> 224 / 8 = 28 .*****...**** -> 1000001110000 -> 4208 / 8 = 526 .******...... -> 1000000111111 -> 4159 / 8 = 519.875 ..*********** -> 1100000000000 -> 6144 / 8 = 768 ....********* -> 1111000000000 -> 7680 / 8 = 960 ........***** -> 1111111100000 -> 8160 / 8 = 1020  So, we extract the kth 'pixel' stored in the bitmask n with: n * 8 >> k & 1  • Sir, would you mind explaining this part [n*8>>k&1])=>~k? – snr Feb 4 at 10:04 • @snr I've added an explanation. Given the operator precedence, n*8>>k&1 should be read as ((n*8)>>k)&1 and means least significant bit of n * 8 right-shifted by k positions. – Arnauld Feb 4 at 10:34 • I'm captivated by your solutions. Actually, you are why I've started learning Javascript . – snr Feb 4 at 10:57 # Retina 0.8.2, 82 bytes  i10¶e18¶c22¶b7c6c7¶b24¶26¶26¶5d10d5¶b5d8d5¶b6jd6¶c22¶e18¶i10 \d+$**
Tld
\d
$*  Try it online! Explanation: Uses run-length encoding, where numbers encode *s and letters b-j encode spaces (so for the 12 spaces of the mouth I need two letters).  i10¶e18¶c22¶b7c6c7¶b24¶26¶26¶5d10d5¶b5d8d5¶b6jd6¶c22¶e18¶i10  Insert the run-length encoded text. \d+$**


Decode integers to runs of *s.

Tld


Replace letters b-j with digits 1-9.

\d

# Japt-R, 66 55 52 bytes

-11 bytes thanks to AZTECCO

"ǿ߿࿧࿿῿῿἟ྏ࿀߿ǿ"¬®c s" *" ê1Ãû


Test it

## Explanation

"..."              // String with characters at codepoints:
//   31   ('        *****' as binary string where ' ' -> 0, '*' -> 1)
//   511  ('    *********' as binary string where ' ' -> 0, '*' -> 1)
//   2047 ('  ***********' as binary string where ' ' -> 0, '*' -> 1)
//   4071 (' *******  ***' as binary string where ' ' -> 0, '*' -> 1)
//   4095 (' ************' as binary string where ' ' -> 0, '*' -> 1)
//   8191 ('*************' as binary string where ' ' -> 0, '*' -> 1)
//   8191 ('*************' as binary string where ' ' -> 0, '*' -> 1)
//   7967 ('*****   *****' as binary string where ' ' -> 0, '*' -> 1)
//   3983 (' *****   ****' as binary string where ' ' -> 0, '*' -> 1)
//   4032 (' ******      ' as binary string where ' ' -> 0, '*' -> 1)
//   2047 ('  ***********' as binary string where ' ' -> 0, '*' -> 1)
//   511  ('    *********' as binary string where ' ' -> 0, '*' -> 1)
//   31   ('        *****' as binary string where ' ' -> 0, '*' -> 1)
¬             // Convert the string to an array
®            // map array with func:
c           //   convert char to codepoint
s" *"     //   convert codepoint to a binary string with chars "* "
ê1   //   concatenate reverse of the binary string to itself
û // centre-pad result of map

The -R flag then concatenates the resulting array with newlines

• 55 – AZTECCO Feb 3 at 21:59
• Nice! I thought it could be still golfed but didn't figured out , btw ê1 can be just ê – AZTECCO Feb 4 at 6:58
• @AZTECCO ê palindromes the string so if length is odd the last char is not added again (e.g. abc -> abcba and not abccba), which causes a * to be removed from all lines – Mukundan314 Feb 4 at 7:24
• Oh! Sorry.. Didn't noticed – AZTECCO Feb 4 at 9:21

# Vyxalj, 50 bytes

»
«0QÞ*⌊B⊍E⟨}¹ǍaȦM.¥⁺⊍Ṅ₂ṖA«[¥ȯ⇩»3τ *
viṅøṀ
€øĊ


Try it Online!

All hail new vertical mirror!!

# Julia, 102 bytes

println.(split(join(collect(" *"^18).^(b"HJKRFVCGBFBGBXAyCJCEAECHCEBFLFCVFRLJ".-64)),r"(?<=\G.{25})"))


Try it online!

the string stores the amount of consecutive ' ' and '*'. We than split the string in 26-character chunks and print with line breaks

# C (gcc), 145 bytes116 Bytes

Thanks to ASCII-only, who managed to shave 29 bytes off.

c;f(i){for(i=0;c="+m'u%y$*%)%j${#}#}#(&-&h$(&+&h$)/i%y'u+-"[i++];c&64&&puts(""))while(--c%64>34)putchar(i&1?32:42);}


Try it online!

I had to start the encoding at 35, since 34 is " which requires an additional \ as escape character and thus would increase the total character count. Each character in the string +m'u%y$*%)%j${#}#}#(&-&h$(&+&h$)/i%y minus 35 represents the number of spaces and asteriks, in an alternating pattern. This achieves a compression rate of almost 8 (318/40).

Ungolfed:

char*s="+m'u%y$*%)%j${#}#}#(&-&h$(&+&h$)/i%y'u+-";
void f()
{
for( int i=0; i < 40; ++i)
{
for(int j=35; j < (s[i]&63); ++j )
{
if( i&1 )
{
printf("*");
}
else
{
printf(" ");
}
}
if( s[i] & 64 )
{
printf("\n");
}
}
}

• Can be squeezed down a bit: 122 bytes – gastropner Feb 3 at 4:13
• 116? – ASCII-only Feb 3 at 4:46
• Suggest printf(L"* "+i%2) instead of putchar(i&1?32:42) – ceilingcat Feb 15 at 4:57

# Pyth, 57 bytes

jm.[26+_K++*\*%/J|Cd390 8 8*\ /J64*\*%J8K\ ",5Ÿ6>>íå5,


Try it online!

## x86-16 machine code, 101 96 bytes

Saved 5 bytes thanks to @peterferrie.

0BEC:0100  BE 44 01 31 DB AD 91 E3-22 51 E8 20 00 59 C1 E9   .D.1...."Q. .Y..
0BEC:0110  03 80 36 2E 01 08 E8 14-00 80 36 2E 01 08 83 FB   ..6.......6.....
0BEC:0120  0C 74 05 B8 0A 00 CD 29-43 EB DA CD 20 D1 E1 19   .t.....)C... ...
0BEC:0130  C0 24 0A 0C 20 83 FB 09-75 03 83 F0 0A CD 29 85   .\$.. ...u.....).
0BEC:0140  C9 75 EA C3 F8 00 F8 0F-F8 3F 38 7F F8 7F F8 FF   .u.......?8.....
0BEC:0150  F8 FF F8 F8 78 7C F8 81-F8 3F F8 0F F8 00 00 00   ....x|...?......


Standalone executable.

Instruction listing (nasm syntax):

org 100h

mov si, face
xor bx, bx
lop:    lodsw
xchg cx, ax
jcxz ed
push cx
call loop
pop cx
shr cx, 3
xor byte [loop+1], 8
call loop
xor byte [loop+1], 8
cmp bx, 12
je sk
mov ax, 0Ah
int 29h
sk: inc bx
jmp lop
ed:
int 20h

loop:   shl cx, 1
sbb ax, ax
and al, 0ah
or al, ' '
cmp bx, 9
jne yy
xor ax, 10
yy: int 29h
test cx, cx
jnz loop
ret

face:   dw 00f8h, 0ff8h, 3ff8h, 7f38h, 7ff8h, 65528, 65528, 63736, \
7c78h, 33272, 3ff8h, 0ff8h, 00f8h, 0000h



## Example run

C:\test>smile.com
**********
******************
**********************
*******  ******  *******
************************
**************************
**************************
*****   **********   *****
*****   ********   *****
******            ******
**********************
******************
**********

• "mov cx, ax" can be "xchg cx, ax". The "jnc" part block can be "sbb ax, ax / and al, 0ah / or al, ' '" – peter ferrie Feb 4 at 22:11

# C (gcc), 175 168 bytes

-7 bytes thanks to ceilingcat

*s;i;p(x,y){for(i=x-printf("%*s",x-97,"");i++<y;printf("*"));s++;}f(){for(s=L"ikjesjcwjbhcgchjbyja{ja{jafdkdfjbfdidfjbgmgjcwjesjikA";*s-'j'?p(*s,s[1]):puts(""),*s++;);}


Try it online!

Explanation before some golfing:

char*s="ikjesjcwjbhcgchjbyja{ja{jafdkdfjbfdidfjbgmgjcwjesjik";


This string encodes the number of consecutive spaces and asterisks along with the newlines position.

p(x,y){for(i=97;i++<x;printf(" "));for(i=97;i++<y;printf("*"));s++;}


This function takes as arguments the ASCII value of two characters and use the first one to print whitespace and the second to print asterisks.

f(){*s-'j'?p(*s,s[1]):puts("");*s++&&f();};


Here we check whether the current character is a 'j', which has been chosen to encode a newline.

• @ceilingcat wow thank you for showing me these tricks! – Sheik Yerbouti Feb 11 at 10:13
• If you switch the string to uppercase then you can compare with 84 instead of 'j'` – ceilingcat Feb 11 at 17:09
• @ceilingcat you are right! This would save another byte. – Sheik Yerbouti Feb 11 at 20:13