# Draw/plot a heart graph

Your challenge is to draw/plot one of the hearts below. The size must be at least 50x50 pixels (vector graphics is OK). You may choose which of the hearts you want to draw/plot. Axes, grid lines etc. are accepted. There must be at least 100 distinct coordinates/points on the graph. The heart can be filled with color if you want to.

The equations are either:

or

$y={cos(t)}^{0.5}\cdot|t|^{0.3}$

t is in the range [-1, 1].

or

or

$r=\frac{sin(t)\sqrt{|cos(t)|}}{sin(t)+\frac{7}{5}}-2sin(t)+2$

This is so the shortest code (in each language) in bytes wins. Please provide the output (or link to an online interpreter).

# TI-80 BASIC, 454341 39 bytes

LBL 1
RAND4-2->X
RAND4-2
IF (X²+ANS²-1)³<X²ANS³
PT-ON(X,ANS
GOTO 1

This took a while, and my battery is low so I didn't want to keep going.

I tried to use the second equation, but couldn't get it to work it actually turned out to be longer, so I just adapted the other answer I had.

EDIT: I just noticed the 50x50 pixel requirement, unfortunately the screen is only 47 pixels high so this isn't possible.

• creative indeed! Commented Feb 13, 2017 at 17:13
• It's been a while, but can you replace IF (X²+ANS²-1)³-X²ANS³<0 with IF (X²+ANS²-1)³<X²ANS³? Commented Feb 15, 2017 at 3:58
• Oh, I can't believe I didn't think of that! thanks Commented Feb 15, 2017 at 13:04

## Perl, 86 bytes

$y=1-$_/25,say+map$y**3*($_*=$_/1e3)-($_+$y**2-1)**3>0?$|--?v60:3:$",-40..40for-6..50 Run with perl -E. Plots a filled ASCII heart, using the first equation. Note that the x-axis is stretched by a factor of ~1.265: this is to counteract the fact that terminal fonts are usually much bigger vertically than horizontally. Output: 3<3<3<3<3<3<3< 3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3<3<3<3<3 <3<3<3<3<3<3<3<3<3< 3<3<3<3<3<3<3<3 <3<3<3<3<3< 3<3<3<3 <3<3< 3 Explanation (since OP asked for it): condition :=$y**3*($_*=$_/1e3)-($_+$y**2-1)**3>0

This is simply the first equation, slightly rearranged to make it shorter. $y directly represents the y in the formula.$_ is initially proportional to x, but is multiply-assigned with itself ($_*=$_/1e3), making it proportional to x². Since x² is used twice in the formula, this saves a few bytes.

1e3 means 1000, and was picked because it’s short and the result looks good. ** is Perl’s power operator. I use >0 rather than ==0 because I want a filled heart.

flip_flop := $|--?v60:3 v60 is an abuse of the archaic version-string syntax to denote the character with ASCII code 60: '<'.$| is a magical variable that can only ever be 0 or 1. Decrementing when it’s already 0 sets it to 1. Decrementing when it’s 1 naturally sets it to 0. Thus, $|-- is often used as a flip-flop: each time it’s evaluated, it alternates between true and false. As a whole, this expression returns alternatively '<' and 3. inner_loop := <condition> ? <flip_flop> :$"

Nested ternaries. If condition is false (→ we’re outside the heart), evaluates to $", which is a magical variable that defaults to " " (a single space). If condition is true (→ we’re inside the heart), it evaluates flip_flop. outer_loop := say+map <inner_loop> ,-40..40 Evaluates inner_loop repeatedly, with$_ (Perl’s “default” variable) going from -40 to 40, in increments of 1. It collects the results of those evaluation in a temporary list, then prints them all, concatenated, ending with a new line.

$y=1-$_/25, <outer_loop> for-6..50

### Output:

OOOOO     OOOOO
.OOOOOOOOO.OOOOOOOOO.
OOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOO
.OOOOOOOOOOOOOOOOOOO.
OOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOO
OOOOOOOOOOO
OOOOO
.

with some empty lines above and below

## JavaScript (ES6), 151 147 bytes

document.write<canvas id=c>;for(i=0;x=2-i/24,i<97;i++)for(j=0;y=2-j/24,z=x*x+y*y-1,j<97;j++)z*z*z-x*x*y*y*y<0&&c.getContext2d.fillRect(i,j,1,1)

Edit: Saved 4 bytes thanks to @user2428118. ES7 version for 143 bytes:

document.write<canvas id=c>;for(i=0;i<97;i++)for(x=2-i/24,j=0;j<97;j++)x*x*(y=2-j/24)**3-(x*x+y*y-1)**3>0&&c.getContext2d.fillRect(i,j,1,1)

• how about y**3 instead of y*y*y ? Commented Feb 14, 2017 at 7:14
• @svarog Thus my note "Would be slightly shorter in ES7"...
– Neil
Commented Feb 14, 2017 at 8:36
• well, it works on chromium 55, so why not add an es7 version ? Commented Feb 14, 2017 at 9:14
• @svarog Because I don't have chromium 55 handy...
– Neil
Commented Feb 14, 2017 at 15:20
• @ThisSuitIsBlackNot It complained about undeclared variables when I tried.
– Neil
Commented Feb 15, 2017 at 18:03

# BBC BASIC, 80

Will finish golfing tomorrow.

ORIGIN99,99F.u=-56TO56x=u/50b=x^2^.33/2r=(b^2-x^2+1)^.5*50L.u,b*50-r,u,r+b*50N.

Draws a filled heart using the first equation, which we rearrange and take the cube root of (there are 3 cube roots of a real number, one real and 2 complex but we only interested in the real root here.) We then rearrange again to get a quadratic in y

x^2+y^2-1=(x^0.66)y

y^2-(x^0.66)y+x^2-1=0

Using the standard quadratic formula for expressions of the type ay^2+by+c=0, and taking advantage of the fact that a=1 we get

y = -b/2 +/- sqrt((b/2)^2-c)

y = -b/2 +/- sqrt((b/2)^2-x^2+1)

where -b/2 = (x^0.66)/2 (represented by b in the program.)

We simply scan through the values of x from left to right, drawing a vertical line between each pair of valid values for y to build up a solid shape.

ORIGIN99,99F.u=-56TO56x=u/50b=x^2^.33/2r=(b^2-x^2+1)^.5*50L.u,b*50-r,u,r+b*50N.

ungolfed

ORIGIN99,99
FORu=-56TO56
x=u/50
b=x^2^.33/2
r=(b^2-x^2+1)^.5*50
LINEu,b*50+r,u,b*50-r
NEXT

## Processing.js: 123 119 bytes

ungolfed:

t = 0;

void setup() {
size(99, 300);
}

void draw() {
point(59+99*sin(t)*cos(t)*log(t),350-400*sqrt(cos(t))*pow(t,0.3));
t+=0.01;
}

golfed:

t=0;void setup(){size(99,300);}void draw(){point(59+99*sin(t)*cos(t)*log(t),350-400*sqrt(cos(t))*pow(t,0.3));t+=0.01;}

this one is quite cheaty as it plots #2 from 0 to infinity instead of from -1 to 1 as shown in the picture to save on the two abs(t). But it's technically correct as there are more than 100 points.

130 bytes "correctier" one

t=-1;void setup(){size(99,300);}void draw(){point(59+99*sin(t)*cos(t)*log(abs(t)),350-400*sqrt(cos(t))*pow(abs(t),0.3));t+=0.01;}

try it online

note : there's probably a way to get 100 points on the default 100x100 canvas and shave the setup off.

• None of your snippets do anything for me on my local version of Processing (except for the second one which just draws 1 point) Commented Feb 13, 2017 at 15:34
• have you tried on sketchpad? ("try it online") you need to click "render sketch" Commented Feb 13, 2017 at 15:35
• But I think that would be called "Processing.JS" instead. For the snippet to work for me, you have to use float instead of int Commented Feb 13, 2017 at 15:37
• oops, forgot the .js, and thanks to that I saved 4 bytes by removing the useless int. Commented Feb 13, 2017 at 15:41

# TI-84 Basic, 40 38 bytes

Similar to @12Me21's answer & output, but for the TI-83/84 series instead.

While 1:2rand-1→A:2rand-1:If (A²+Ans²-1)³>A²Ans³:Pt-On(A,Ans:End
• Is using Ans actually smaller here? I thought Ans was 2 bytes. Commented Feb 13, 2017 at 16:48
• @12Me21 No, it's the same size, and faster too. (For TI-83/84 at least, I don't know about TI-80). Commented Feb 13, 2017 at 16:52

# BBC BASIC (BBC Micro) (126 bytes)

This is a variation of Level River Street's answer, but for the original BBC Micro's iteration of BBC BASIC.

You can copy and paste either of the following into JSBeeb's new paste functionality at https://bbc.godbolt.org/ (A JavaScript powered BBC Micro emulator), once it has pasted, press Enter inside the 'screen' to show a new prompt, then type RUN, then press Enter to run either version.

golfed. (126 bytes)

1MO.1:V.29,64;64;:MOVE-57,20:GC.0,1:F.U=-56TO56:X=U/50:IFX<>0TH.B=X^2^.33/2
2R=(B^2-X^2+1)^.5*50:DRAWU,B*50+R:DRAW U,B*50-R:N.

ungolfed. (176 bytes)

1 MODE 1
2 VDU 29,64;64;
3 MOVE -57,20
4 GCOL 0,1
5 FOR U = -56 TO 56
6 X = U/50
7 IF X <> 0 THEN B = X^2^.33/2
8 R = (B^2-X^2+1)^.5*50
9 DRAW U,B*50+R
10 DRAW U,B*50-R
11 NEXT

Line 7 requires a check for X, to prevent a "Log range" error when X becomes 0 half way through the loop. Other than this, it's pretty much the same. It's a lot slower to draw on a real machine, which JSBeeb emulates pretty well.

# Google Sheets (Conditional Formatting), 73

Set conditional formatting on range A1:CV100:

=(2500/9-(Column()-25)^2-(ROW()-25)^2)^3>(Column()-25)^2*(ROW()-25)^3/.06

You'll have to adjust your columns/rows so that 100x100 cells fit on your screen. (10 pixels is a good value.) Colors the cells in the cardioid.