15
\$\begingroup\$

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.

\$\endgroup\$
4
  • 3
    \$\begingroup\$ I prefer it with bigger eyes, must be the kawaii manga effet \$\endgroup\$
    – Kaddath
    Commented Feb 2, 2021 at 11:10
  • 4
    \$\begingroup\$ Pretty close... \$\endgroup\$
    – user202729
    Commented Feb 2, 2021 at 13:32
  • \$\begingroup\$ Very similar, potential dupe \$\endgroup\$ Commented Feb 3, 2021 at 20:15
  • \$\begingroup\$ Note: I forgot to add a tiebreak, so until the tie between ovs 's 05AB1E answer and xigoi 's Jelly answer is resolved, no accepting. \$\endgroup\$
    – emanresu A
    Commented Feb 25, 2021 at 10:13

27 Answers 27

7
\$\begingroup\$

Python 3, 97 93 bytes

Thanks to Mukundan314 for -4 bytes!

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

for c in"%.»677íìư.%":c=ord(c);s=c//8%8*'*'+c//64*' '+c%8*'*';print(f'{s+s[::-1]:^26}')

Try it online!

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

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

\$\endgroup\$
4
\$\begingroup\$

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 ("").

\$\endgroup\$
4
\$\begingroup\$

TI-BASIC, 172 bytes (on-calc) / 205 bytes (as text)

Conveniently, the image is exactly as wide as the screen on the TI-84 Plus CE. This should work with an 83/84(+) too, but it won't display properly due to the smaller screens.

{7,10,12,18,6,22,3,7,2,6,2,7,2,24,1,57,3,10,3,5,1,5,3,8,3,5,2,6,12,6,3,22,6,18,12,10,8→D
" 
For(I,1,37
For(J,1,⌊D(I
Ans+sub("* ",remainder(I,2)+1,1
End
End
For(I,1,338,26
Disp sub(Ans,I,26
End

Explanation

  • {7,10,12,18,6,22,3,7,2,6,2,7,2,24,1,57,3,10,3,5,1,5,3,8,3,5,2,6,12,6,3,22,6,18,12,10,8→D: Stores a list of the number of spaces and asterisks, alternating, like the lines of the image are unwrapped in 1-D space one after the other. The first value is an exception; it should theoretically be 8, but since TI-BASIC doesn't like empty strings, the output string is created with a single space already in it.
  • " : Create a string in the Ans "variable" with a single space in it.
  • For(I,1,37: For (the index of) each value in ⌊D...
    • For(J,1,⌊D(I
      • Ans+sub("* ",remainder(I,2)+1,1: ...concatenate that number of either asterisks or spaces to the string, depending on whether I, the index of the list, is odd or even.
    • End
  • End
  • For(I,1,338,26: For I from 1 to 338 (length of the resulting string) with a step of 26 (length of each row of the image)...
    • Disp sub(Ans,I,26: ...display a substring starting at I (the start of the I-th row of the image) which is 26 characters long.
  • End
\$\endgroup\$
3
  • \$\begingroup\$ Welcome to Code Golf, and nice first answer! Would it be possible to add a link to an online TI emulator or something? \$\endgroup\$
    – user
    Commented Jul 29, 2021 at 23:53
  • 1
    \$\begingroup\$ Unfortunately no. An emulator like jsTIfied requires the user to upload a calculator ROM image. \$\endgroup\$
    – orangey
    Commented Jul 30, 2021 at 0:19
  • \$\begingroup\$ did you try this trick to golf the list ? \$\endgroup\$
    – MarcMush
    Commented Aug 30, 2021 at 8:29
3
\$\begingroup\$

05AB1E, 72 68 42 bytes

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

-26 bytes by adding a mirror (inspired by @Neil's Charcoal answer).

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.

\$\endgroup\$
3
\$\begingroup\$

PHP, (all versions) 119 106 104 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)

\$\endgroup\$
8
  • \$\begingroup\$ 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= \$\endgroup\$
    – hanshenrik
    Commented Feb 2, 2021 at 19:56
  • \$\begingroup\$ shaved off a few more bytes (more efficient NULL-encoding), now it's 72 bytes: PD89Z3ppbmZsYXRlKCdTUIAALTjg5ULlI4tjikJloCyYCrhKhBQWXbhkiJJDcSOMA7MOSRJdSksBCcAdidtnOMMCPdwAJyk7 \$\endgroup\$
    – hanshenrik
    Commented Feb 2, 2021 at 20:08
  • \$\begingroup\$ (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 =/ ) \$\endgroup\$
    – hanshenrik
    Commented Feb 2, 2021 at 20:24
  • \$\begingroup\$ 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. \$\endgroup\$
    – emanresu A
    Commented Feb 3, 2021 at 4:07
  • \$\begingroup\$ @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 \$\endgroup\$
    – Kaddath
    Commented Feb 3, 2021 at 8:06
3
\$\begingroup\$

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
\$\endgroup\$
3
  • \$\begingroup\$ Sir, would you mind explaining this part [n*8>>k&1])=>~k? \$\endgroup\$ Commented Feb 4, 2021 at 10:04
  • 1
    \$\begingroup\$ @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. \$\endgroup\$
    – Arnauld
    Commented Feb 4, 2021 at 10:34
  • \$\begingroup\$ I'm captivated by your solutions. Actually, you are why I've started learning Javascript . \$\endgroup\$ Commented Feb 4, 2021 at 10:57
2
\$\begingroup\$

Charcoal, 36 bytes

⭆”←&∨n?Þ\`W!π↖δ℅If#≕W⧴@b⪪¹λ”∨×Σι*ι‖M←

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.

‖M←

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).

\$\endgroup\$
2
\$\begingroup\$

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!

\$\endgroup\$
1
  • \$\begingroup\$ 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! \$\endgroup\$ Commented Feb 3, 2021 at 12:49
2
\$\begingroup\$

Vyxal j, 50 bytes

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

Try it Online!

All hail new vertical mirror!!

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

///, 121 bytes

/4/33//3/22//2/11//1/**//8/99//9/00//0/  /813
914
0124
 *120120*12
 34
134
134
*2 013 0*2
 *2 03 0*2
 129812
0124
914
813

Try it online!

Will add explanation soon!

In the meantime, if this isn't obscure enough, see if you can figure this one out!

\$\endgroup\$
2
\$\begingroup\$

Vim, 82 bytes

13i*<esc>Ypr Yppr p3r p7r :g/^/t0
3j2r 3jYp6|3r jh3r jh6r :%s/\v(\*+)( *)(.*)/&\3\2\1

Try it online!

Explanation

Approach: 1) Make a quarter-circle with asterisks. 2) Mirror it vertically. 3) Replace some of the asterisks with spaces. 4) Mirror it horizontally.

13i*<esc>

Insert 13 asterisks.

Ypr<spc>

Make a copy of the line and replace the first character of the copy with a space.

Yppr<spc>

Make two copies of that line. Replace the first non-space character of the second copy with a space.

p3r<spc>p7r<spc>

Paste another copy and replace the first three characters with spaces; paste one more copy and replace the first seven characters with spaces.

:g/^/t0<nl>

A modified version of this trick for reversing the lines in the buffer: instead of moving each line to the beginning with m0, copy it to the beginning with t0, effectively mirroring the whole buffer upward.

3j2r<spc>

The cursor is on the first asterisk of the top line; if we go down three times, we happen to land on the leftmost character that should become the eye. Replace two characters with spaces.

3jYp

Go down three more times and make a copy of the line. (This is the center line; we need three copies of it, but the mirroring code left us with only two.)

6|3r<spc>

Go to the sixth character; replace three characters with spaces.

jh3r<spc>

Go down one line, go left one column, and replace three characters with spaces.

jh6r<spc>

Go down and left again and replace six characters with spaces.

:%s/\v

On all lines, substitute (using the "very magic" setting so we don't have to backslash all the parentheses)...

(\*+)( *)(.*)

... one or more asterisks, zero or more spaces, and the rest of the line if any...

/&\3\2\1<cr>

... with the full match followed by the three capture groups in reverse order.

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

05AB1E, 33 32 bytes

-1 byte thanks to Kevin Cruijssen!

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

•γÂÂàª[O‘ôγ̹‚5•₄;вε8в„* Þ×J}º.c

Try it online!

Commented:

•γÂÂàª[O‘ôγ̹‚5•₄;в  # 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
\$\endgroup\$
1
  • 1
    \$\begingroup\$ •Uмö€æ¤š∊η ø‘Kó•468в can be •γÂÂàª[O‘ôγ̹‚5•₄;в for -1. And you've made a typo in your explanation: the should be . Nice approach btw! \$\endgroup\$ Commented Feb 2, 2021 at 20:30
1
\$\begingroup\$

Retina 0.8.2, 82 bytes


i10¶e18¶c22¶b7c6c7¶b24¶26¶26¶5d10d5¶b5d8d5¶b6jd6¶c22¶e18¶i10
\d+
$**
T`l`d
\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.

T`l`d

Replace letters b-j with digits 1-9.

\d
$* 

Decode digits to runs of spaces.

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

Bubblegum, 49 bytes

Obligatory bubblegum entry. Generated with zopfli --i1000 --deflate -c smiley.txt | xxd.

00000000: 5380 022d 38e0 42e6 a208 8369 4c09 9838  S..-8.B....iL..8
00000010: 4401 8246 c860 ea01 6272 a560 ae83 71a0  D..F.`..br.`..q.
00000020: 56c1 b898 3230 3e02 60f5 11e1 10c0 0c2b  V...20>.`......+
00000030: 00                                       .

Try it online!

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

Jelly, 35 33 bytes

“ ṄUçɓĠḷƑżØS`’b12o43µ⁾ *ṁxs13m€0Y

Try it online!

Explanation

“ ṄUçɓĠḷƑżØS`’b12o43µ⁾ *ṁxs13m€0Y   Main monadic link
“ ṄUçɓĠḷƑżØS`’                      8060783762011200773438708597
              b12                   Convert to base 12 => [8,5,4,9,2,11,1,7,2,3,1,0,3,5,1,5,3,4,1,6,8,11,4,9,8,5]
                 o43                Logical OR with 43 => [8,5,4,9,2,11,1,7,2,3,1,43,3,5,1,5,3,4,1,6,8,11,4,9,8,5]
                    µ               Use as argument to new monadic chain
                     ⁾ *ṁ           Repeat " *" to have the same length
                         x          Repeat each character as many times as the corresponding number
                          s13       Split into chunks of 13
                             m€0    Mirror each
                                Y   Join with newlines
\$\endgroup\$
1
\$\begingroup\$

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

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

Perl 5 -M5.10.0, 73 bytes

$_=unpack"B*","......w......|{.......";y/01/ */,say$_.reverse for/.{13}/g

Try it online!

Explanation

This solution consists of mostly unprintable characters which are a packed binary string containing a representation of the left-half of the image as 0s and 1s which is unpacked into $_, then y/// (tr///) changes all the 0s to s and the 1s to *s, before the /.{13}/g (m//) matches each stretch of 13 chars passing them to say ($_), along with the reverse of $_, to print the result on individual lines.

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

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
\$\endgroup\$
4
  • \$\begingroup\$ 55 \$\endgroup\$
    – AZTECCO
    Commented Feb 3, 2021 at 21:59
  • \$\begingroup\$ Nice! I thought it could be still golfed but didn't figured out , btw ê1 can be just ê \$\endgroup\$
    – AZTECCO
    Commented Feb 4, 2021 at 6:58
  • \$\begingroup\$ @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 \$\endgroup\$ Commented Feb 4, 2021 at 7:24
  • \$\begingroup\$ Oh! Sorry.. Didn't noticed \$\endgroup\$
    – AZTECCO
    Commented Feb 4, 2021 at 9:21
1
\$\begingroup\$

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
        **********
    ******************
  **********************
 *******  ******  *******
 ************************
**************************
**************************
*****   **********   *****
 *****   ********   *****
 ******            ******
  **********************
    ******************
        **********
\$\endgroup\$
1
  • \$\begingroup\$ "mov cx, ax" can be "xchg cx, ax". The "jnc" part block can be "sbb ax, ax / and al, 0ah / or al, ' '" \$\endgroup\$ Commented Feb 4, 2021 at 22:11
1
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ @ceilingcat wow thank you for showing me these tricks! \$\endgroup\$
    – anotherOne
    Commented Feb 11, 2021 at 10:13
  • \$\begingroup\$ If you switch the string to uppercase then you can compare with 84 instead of 'j' \$\endgroup\$
    – ceilingcat
    Commented Feb 11, 2021 at 17:09
  • \$\begingroup\$ @ceilingcat you are right! This would save another byte. \$\endgroup\$
    – anotherOne
    Commented Feb 11, 2021 at 20:13
1
\$\begingroup\$

Python, 142 140 bytes

for x in"销夀㬀✣Ⰰᴀᴀᔵ┴♠㬀夀销":a,b,c,d=[int(x,16)for x in hex(ord(x))[2:]];s=' '*(a-1)+'*'*b+' '*c+'*'*d;print(s+s[::-1])

Try it online

This is very... stupid. It's in the vein of another Python answer but uses a more naive encoding:

(number of alternating spaces and asterisks in half of the image.)
_ *  _ *
========
9 5  0 0  \u9500 销
5 9  0 0  \u5900 夀
3 11 0 0  \u3b00 㬀
2 7  2 3  \u2723 ✣
2 12 0 0  \u2c00 Ⰰ
1 13 0 0  \u1d00 ᴀ
1 13 0 0  \u1d00 ᴀ
1 5  3 5  \u1535 ᔵ
2 5  3 4  \u2534 ┴
2 6  6 0  \u2660 ♠
3 11 0 0  \u3b00 㬀
5 9  0 0  \u5900 夀
9 5  0 0  \u9500 销
\$\endgroup\$
4
  • \$\begingroup\$ 114 chars, 140 bytes (UTF-8) \$\endgroup\$
    – user100411
    Commented Jul 17, 2021 at 9:48
  • \$\begingroup\$ Oops, sorry for that. \$\endgroup\$
    – daylily
    Commented Jul 17, 2021 at 14:20
  • \$\begingroup\$ Also sorry for not clarifying that I golfed it a bit on first comment. \$\endgroup\$
    – user100411
    Commented Jul 18, 2021 at 0:45
  • \$\begingroup\$ Ahh I was too stupid. \$\endgroup\$
    – daylily
    Commented Jul 18, 2021 at 1:27
1
\$\begingroup\$

Excel, 111 bytes

Formula, 60 bytes

=CONCAT(IF(A1:A32="","
",REPT(" ",A1:A32)&REPT("*",B1:B32)))

Data in cells, 51 bytes

A B
1 8 10
2
3 4 10
4
5 2 22
6
7 1 7
8 2 6
9 2 7
10
11 1 24
12
13 0 26
14
15 0 26
16
17 0 5
18 3 10
19 3 5
20
21 1 5
22 3 8
23 3 5
24
25 1 6
26 12 6
27
28 2 22
29
30 4 18
31
32 8 10

Link to Spreadsheet

Column A indicates the number of " "; Column B the number of "*". If column A is "" then add a line feed.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Excel says there's a problem with the formula \$\endgroup\$ Commented Jul 29, 2021 at 13:22
  • \$\begingroup\$ Reformatted the answer and added link to make more clear. \$\endgroup\$
    – Axuary
    Commented Jul 29, 2021 at 21:54
0
\$\begingroup\$

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");
        }
   }
}
\$\endgroup\$
3
  • \$\begingroup\$ Can be squeezed down a bit: 122 bytes \$\endgroup\$
    – gastropner
    Commented Feb 3, 2021 at 4:13
  • \$\begingroup\$ 116? \$\endgroup\$
    – ASCII-only
    Commented Feb 3, 2021 at 4:46
  • \$\begingroup\$ Suggest printf(L"* "+i%2) instead of putchar(i&1?32:42) \$\endgroup\$
    – ceilingcat
    Commented Feb 15, 2021 at 4:57
0
\$\begingroup\$

Pyth, 57 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Python 3.8 (pre-release), 123 bytes

print(''.join(['\n',['*'*x,' '*-x][x<0]][x!=0]for x in(y-90for y in b'RdZVlZXpZYaX`XaZYrZtZtZ_WdW_ZY_WbW_ZY`N`ZXpZVlZRd')))

Try it online!

Explanation

The list-switch part outputs newlines when x is 0, x number of '*' characters when x > 0, and -x number of ' ' characters when x < 0. I think of it as abs(x) characters, where the sign determines which character I'm writing.

The byte list comprehension subtracts 90 from each byte in the buffer to feed the outer comprehension the expected values centered at 0, since a buffer can't hold negatives in a literal (afaik).

Used a script to encode the smiley face as character run lengths to create the bytes literal... I think I lost the original but may add it later.

\$\endgroup\$
0
\$\begingroup\$

JavaScript (Node.js), 249 bytes

s=`\t*****
    *********
  ***********
 *******  ***
 ************
*************
*************
*****   *****
 *****   ****
 ******      
  ***********
    *********
\t*****`;s=s.split`\n`;s=s.map(l=>l+[...l].reverse().join``);console.log(s.join`\n`)

Try it online!

\$\endgroup\$

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.