| Bytes | Lang | Time | Link |
|---|---|---|---|
| 366 | JavaScript Node.js | 240103T063707Z | l4m2 |
| 511 | Python | 240103T064148Z | Command |
JavaScript (Node.js), 366 bytes
P=(a,b=0,c=0,d=0,e=0)=>console.log(a,b,c,d,e)
L=x=>P(0,x)|P(x)|P(y=x+'/2',z=x+'/2*s3')|P(y,z,0,0,1)|P(x,z+'*2',x,0,1)
S=(b,a)=>`(${P(0,0,1,0,1),P(0,0,b)|P(b)|P(b+'/2',b+'/2*s3',a),b}-${a})`
D=(a,b)=>S(1,`(1-${P(a,0,S(a,b))|L(a)|L(1)|P(1,0,1,z=`(${a}/${b})`),z})`)
s=a=>P(S(0,1),0,a)|P(a,0,-1)|P(z=`(${a}-1)/2`,y=`(${a}+1)/2*s3`,z,-1+y,1)|P(z,0,a)|P(0,0,0,z='s'+a)||z
-24 from emanresu A
0 a b c d mean circle (a,b) through (c,d)
1 a b c d mean line through (a,b) and (c,d)
Should be quite golfable
Lprovides line \$x=x_0\$, assuming \$x_0 \neq 0\$Ssubtracts two valuesDdivides two values while creating point with given coordssgives square root
Notes
- Need confirm
- Some free points may sometimes give good: To draw \$x=0\$, a sequence
Line((0,0),(1,0)), Circle((a,b),(0,0)), Line((2a,0),(a,b)), Line((0,2b)-(0,0))should be shorter than always based on existing points, but that'd be complex-expressed - Since taking a sequence of operations also "can represent any closed form number exactly and unambiguously", I assume it be a subset of
+-*/sqrt
Python, 511 bytes
l=[(1,0,0,1,0)]
z,o='01'
def a(b,c):e=f'da{b}{c}2';v='dtm%s%ss32';l.extend([(0,b,0,c,0),(0,c,0,b,0),(1,e,v%(b,c),e,v%(c,b)),(0,e,0,0,0)]);return'a'+b+c
def m(b,c):l.append((0,0,0,c,0));return a(b,'m0'+c)
def t(b,c):l.append((1,0,p(b),p(c),p(m(b,o))));return't'+b+c
def d(b,c):l.append((1,0,1,p(b),p(m(o,c))));return'd'+b+c
def s(b):v=d(m(b,o),a(o,o));l.append((0,0,v,0,'m01'));return's'+b
def p(b):a(a(b,b),z);l.extend((a,c,b,e,d) for a,b,c,d,e in l[:]);return b
m(o,o)
def e(b,c):p(eval(b));p(eval(c));return l
If we can assume the user evaluated the functions (so we don't have to call eval), we can just do e=lambda a,b:l.
The function is e, it takes as input the two coordinates. a is addition, m subtraction, t multiplication, d division, and s square root. o has to be used in place of 1, and z in place of 0.
Returns a list of objects to create, specifying coordinates in prefix notation, with single digits (so a32 = 5).
Here's how it works for \$(\sqrt2, 3)\$, for example:
The animation code:
import math
import matplotlib.pyplot as plt
from matplotlib import animation
from matplotlib.patches import Circle
def calc(s: str):
if type(s) is int:
return s, ''
if s[0].isdigit():
return int(s[0]), s[1:]
v1, rem = calc(s[1:])
if s[0] == 's':
return v1**.5, rem
v2, rem = calc(rem)
return (v1+v2 if s[0]=='a' else v1-v2 if s[0]=='m' else v1*v2 if s[0]=='t' else v1/v2 if s[0]=='d' else None), rem
var = plt.subplots()
fig : plt.Subplot = var[0]
ax : plt.Axes = var[1]
artists = []
points = set()
dat = e('s(a(o,o))','s(a(o,a(o,o)))')
print(len(dat))
ax.axis('equal')
ax.plot(2**.5, 3**.5, 'bo')
objects = set()
for a, b, c, d, e in dat:
b, c, d, e = (calc(x)[0] for x in (b, c, d, e))
if (a,b,c,d,e) in objects:
continue
objects.add((a,b,c,d,e))
if (b, c) not in points:
artists.append(ax.plot(b, c, 'ro')[0])
points.add((b, c))
if (d, e) not in points:
artists.append(ax.plot(d, e, 'ro')[0])
points.add((d, e))
if a == 1 and (b,c) != (d,e):
artists.append(ax.axline((b,c),(d,e)))
else:
artists.append(ax.add_patch(Circle((b,c), math.hypot(b-d, c-e), fill=False)))
def update(frame):
for i, art in enumerate(artists):
art.set_visible(i < frame)
ani = animation.FuncAnimation(fig=fig, func=update, frames=len(artists)+20, interval=100)
plt.interactive(True)
plt.show(block=True)
