Model profile
Claude Fable
29/29answered (R1–R30)
0DNF / pending
8.58avg. score · 19 scored rounds (R1–R30)
Rounds & answers 24
▶ R6 · Extraction → JSON Open round →
{"name": "AquaPur X2", "brand": "PetFlow", "price_eur": 29.99, "weight_g": 800, "features": ["Dreifach-Filter", "leises 2-Watt-Pumpsystem", "spülmaschinenfester Edelstahlaufsatz"], "in_stock": false}▶ R7 · Sentiment classification Open round →
[{"id":1,"sentiment":"positive"},{"id":2,"sentiment":"negative"},{"id":3,"sentiment":"neutral"},{"id":4,"sentiment":"negative"},{"id":5,"sentiment":"positive"},{"id":6,"sentiment":"neutral"},{"id":7,"sentiment":"neutral"},{"id":8,"sentiment":"negative"},{"id":9,"sentiment":"positive"},{"id":10,"sentiment":"neutral"}]▶ R8 · Translation DE↔EN Open round →
That's old hat — history punishes those who show up late. We hauled the cart out of the mud, but let's not get ahead of ourselves now. --- Probieren geht über Studieren: Unser Minibudget zwang uns, an allen Ecken zu sparen — und trotzdem ging der Launch über die Bühne, ohne dass es auch nur einmal gehakt hätte.
▶ R9 · One-liner code Open round →
1. ^\d{4}-(0[1-9]|1[0-2])-\d{2}$
2. SELECT customer_id, SUM(amount) AS total FROM orders GROUP BY customer_id ORDER BY total DESC LIMIT 5;
3. .items[].id
4. nav a[href^="http"]
5. cut -d' ' -f1 access.log | sort -u | wc -l▶ R10 · Facts quiz Open round →
1. Canberra 2. 1989 3. W 4. I'm a teapot 5. Franz Kafka 6. Saturn 7. 101010 8. 443 9. Linus Torvalds 10. 97
▶ R11 · Micro-copy & slogans Open round →
1. Moving water, happier cat. 2. Baked before you wake. 3. Every model. One prompt. No spin. 4. Turn the world down. 5. One password. Zero worries.
▶ R13 · Image prompts Open round →
1. Ergonomic gaming chair as the hero, backlit by magenta-cyan neon strips in a streamer's room, RGB keyboard glow reflecting off matte black leather, shallow depth of field, moody cinematic contrast, 35mm look. 2. Craft gin bottle on a walnut bar counter, embossed label catching warm amber backlight, condensation beads, blurred bottle shelf and brass rail behind, evening speakeasy mood, macro product photography. 3. Matte-grey e-scooter leaning on a vivid graffiti wall, low morning sun raking across wet asphalt, long shadows, steam from a coffee cup on the curb, urban documentary style, 28mm.
▶ R14 · Product names Open round →
1. SipSense — Your bottle knows when. 2. DrinkPing — Hydration, right on schedule. 3. AquaNudge — A gentle push to sip. 4. WellSpring — Smart water, smarter you. 5. Drop — Never miss a sip.
▶ R15 · CSS spinner Open round →
<div class="spinner"></div>
<style>
.spinner{
width:44px;height:44px;border-radius:50%;
border:4px solid rgba(94,234,212,.15);
border-top-color:#5eead4;
animation:spin .8s cubic-bezier(.6,.2,.4,.8) infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}
</style>▶ R16 · Explain it to a child (German) Open round →
Ein Akku ist wie eine kleine Lunchbox für Strom: Wenn du ihn auflädst, packst du Energie hinein, so wie Mama dir Brote einpackt. Drinnen wandern winzige Teilchen von einer Seite zur anderen und merken sich dabei die Energie. Wenn du dein Gerät benutzt, wandern die Teilchen zurück und geben die Energie wieder ab — die Lunchbox wird sozusagen leergegessen. Ist alles aufgebraucht, steckst du den Akku ans Ladegerät und packst die Box einfach neu voll.
▶ R17 · Logic riddle★ 9.5/10 Open round →
Ich ziehe aus der Kiste mit dem Etikett „Gemischt" — da alle Etiketten falsch sind, enthält sie in Wahrheit nur eine Sorte. Ziehe ich einen Apfel, ist das die Äpfel-Kiste. Die mit „Birnen" beschriftete Kiste kann weder Birnen (falsches Etikett) noch Äpfel (bereits vergeben) enthalten, ist also die gemischte Kiste. Die mit „Äpfel" beschriftete Kiste enthält folglich die Birnen; ziehe ich stattdessen eine Birne, gilt dieselbe Logik spiegelverkehrt.
▶ R18 · German registers & tone★ 9.5/10 Open round →
1. Sehr geehrte Damen und Herren, wir bedauern, Ihnen mitteilen zu müssen, dass wir den zugesagten Liefertermin nicht einhalten können, und informieren Sie umgehend über den neuen Termin. 2. Status-Update: Der geplante Liefertermin kann nicht gehalten werden — neuer Termin wird ermittelt und hier gepostet. 3. Du, der Liefertermin platzt uns leider — ich geb dir Bescheid, sobald ich den neuen habe.
▶ R19 · Table QA★ 10/10 Open round →
1. VitaSip 2. 830 3. PureFlow 4. 19,51 5. 3
▶ R20 · JSON repair★ 10/10 Open round →
{"name": "Trinkflasche Pro", "price": 29.90, "tags": ["outdoor", "sport"], "stock": {"berlin": 12, "muenchen": 7, "hamburg": null}, "active": true}▶ R21 · Sorting race bubble/insertion/selectionOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sorting Race</title>
<style>
body{background:#0b1220;color:#e6e9f0;font-family:system-ui;text-align:center}
.row{display:flex;gap:12px;justify-content:center;margin-top:20px}
.panel{background:#121a30;border:1px solid #26304d;border-radius:8px;padding:10px}
h3{margin:4px 0 8px;font-size:14px}
.done{color:#34d399;font-weight:bold;height:18px;font-size:13px}
</style>
</head>
<body>
<h1>Sorting Race: Bubble vs Insertion vs Selection</h1>
<div class="row">
<div class="panel"><h3>Bubble</h3><canvas id="c0" width="240" height="160"></canvas><div class="done" id="d0"></div></div>
<div class="panel"><h3>Insertion</h3><canvas id="c1" width="240" height="160"></canvas><div class="done" id="d1"></div></div>
<div class="panel"><h3>Selection</h3><canvas id="c2" width="240" height="160"></canvas><div class="done" id="d2"></div></div>
</div>
<script>
const N=40, base=Array.from({length:N},()=>Math.random()*150+5);
function* bubble(a){for(let i=0;i<N;i++)for(let j=0;j<N-1-i;j++){if(a[j]>a[j+1]){[a[j],a[j+1]]=[a[j+1],a[j]];}yield;}}
function* insertion(a){for(let i=1;i<N;i++){let k=a[i],j=i-1;while(j>=0&&a[j]>k){a[j+1]=a[j];j--;yield;}a[j+1]=k;yield;}}
function* selection(a){for(let i=0;i<N;i++){let m=i;for(let j=i+1;j<N;j++){if(a[j]<a[m])m=j;yield;}[a[i],a[m]]=[a[m],a[i]];yield;}}
const runs=[bubble,insertion,selection].map((g,i)=>({
arr:base.slice(), gen:null, ctx:document.getElementById('c'+i).getContext('2d'),
done:false, el:document.getElementById('d'+i), make:g
}));
runs.forEach(r=>r.gen=r.make(r.arr));
function draw(r){
r.ctx.clearRect(0,0,240,160);
r.ctx.fillStyle=r.done?'#34d399':'#7aa2ff';
const w=240/N;
r.arr.forEach((v,i)=>r.ctx.fillRect(i*w,160-v,w-1,v));
}
function tick(){
let running=false;
runs.forEach(r=>{
if(!r.done){
if(r.gen.next().done){r.done=true;r.el.textContent='DONE';}
running=true;
}
draw(r);
});
if(running)requestAnimationFrame(tick);
}
tick();
</script>
</body>
</html>▶ R22 · Hexagon ballsOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Spinning Hexagon Balls</title>
<style>body{margin:0;height:100vh;display:flex;align-items:center;justify-content:center;background:#111}canvas{background:#000}</style>
</head>
<body>
<canvas id="c" width="600" height="600"></canvas>
<script>
const ctx=document.getElementById("c").getContext("2d");
const CX=300,CY=300,A=240,RV=A/Math.cos(Math.PI/6),G=0.08,OM=0.004;
let th=0;
const balls=[];
for(let i=0;i<8;i++){
const a=i/8*Math.PI*2;
balls.push({x:CX+Math.cos(a)*120,y:CY+Math.sin(a)*120,vx:(Math.random()-.5)*5,vy:(Math.random()-.5)*5,r:14,c:"hsl("+i*45+",85%,60%)"});
}
function physics(){
th+=OM;
for(const b of balls){b.vy+=G;b.x+=b.vx;b.y+=b.vy;}
for(let i=0;i<8;i++)for(let j=i+1;j<8;j++){
const p=balls[i],q=balls[j],dx=q.x-p.x,dy=q.y-p.y,d=Math.hypot(dx,dy),m=p.r+q.r;
if(d>0&&d<m){
const nx=dx/d,ny=dy/d,rel=(p.vx-q.vx)*nx+(p.vy-q.vy)*ny;
if(rel>0){p.vx-=rel*nx;p.vy-=rel*ny;q.vx+=rel*nx;q.vy+=rel*ny;}
const ov=(m-d)/2;p.x-=ov*nx;p.y-=ov*ny;q.x+=ov*nx;q.y+=ov*ny;
}
}
for(const b of balls)for(let k=0;k<6;k++){
const a=th+k*Math.PI/3,nx=Math.cos(a),ny=Math.sin(a);
const d=(b.x-CX)*nx+(b.y-CY)*ny;
if(d>A-b.r){
const wx=-OM*(b.y-CY),wy=OM*(b.x-CX);
const vn=(b.vx-wx)*nx+(b.vy-wy)*ny;
if(vn>0){b.vx-=2*vn*nx;b.vy-=2*vn*ny;}
const pen=d-(A-b.r);b.x-=pen*nx;b.y-=pen*ny;
}
}
}
function draw(){
ctx.fillStyle="#000";ctx.fillRect(0,0,600,600);
ctx.strokeStyle="#5af";ctx.lineWidth=4;ctx.beginPath();
for(let k=0;k<6;k++){
const a=th+Math.PI/6+k*Math.PI/3,px=CX+RV*Math.cos(a),py=CY+RV*Math.sin(a);
k?ctx.lineTo(px,py):ctx.moveTo(px,py);
}
ctx.closePath();ctx.stroke();
for(const b of balls){ctx.fillStyle=b.c;ctx.beginPath();ctx.arc(b.x,b.y,b.r,0,7);ctx.fill();}
}
function loop(){physics();physics();draw();requestAnimationFrame(loop);}
loop();
</script>
</body>
</html>▶ R23 · Pendulum waveOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Pendulum Wave</title>
<style>body{margin:0;background:#0b0e14;display:flex;justify-content:center;align-items:center;height:100vh}</style>
</head>
<body>
<canvas id="c" width="900" height="520"></canvas>
<script>
const ctx=document.getElementById("c").getContext("2d");
const N=15,CYC=40,BASE=25,PY=40,AMP=0.3;
const ps=[];
for(let i=0;i<N;i++){
const f=(BASE+i)/CYC;
ps.push({px:170+i*40,f:f,L:170/(f*f),c:"hsl("+i*24+",80%,60%)"});
}
const t0=performance.now();
function loop(now){
const t=(now-t0)/1000;
ctx.fillStyle="#0b0e14";ctx.fillRect(0,0,900,520);
ctx.strokeStyle="#778";ctx.lineWidth=6;
ctx.beginPath();ctx.moveTo(150,PY);ctx.lineTo(750,PY);ctx.stroke();
for(const p of ps){
const th=AMP*Math.cos(2*Math.PI*p.f*t);
const bx=p.px+p.L*Math.sin(th),by=PY+p.L*Math.cos(th);
ctx.strokeStyle="#99a";ctx.lineWidth=1.5;
ctx.beginPath();ctx.moveTo(p.px,PY);ctx.lineTo(bx,by);ctx.stroke();
ctx.fillStyle=p.c;ctx.beginPath();ctx.arc(bx,by,11,0,7);ctx.fill();
}
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
</script>
</body>
</html>▶ R24 · Maze race BFS/DFS/A*STAT★ 8.5/10 Open round →
📝 clearest rendering: real mazes, yellow path clearly visible, DONE (8.5)
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Pathfinding Race</title>
<style>
body{margin:0;background:#14171f;color:#eee;font-family:monospace;display:flex;justify-content:center;align-items:center;height:100vh}
.row{display:flex;gap:24px}
.p{text-align:center}
.lb{margin-bottom:6px;font-size:16px}
canvas{border:1px solid #444}
</style>
</head>
<body>
<div class="row">
<div class="p"><div class="lb" id="l0">BFS</div><canvas id="c0" width="250" height="250"></canvas></div>
<div class="p"><div class="lb" id="l1">DFS</div><canvas id="c1" width="250" height="250"></canvas></div>
<div class="p"><div class="lb" id="l2">A*</div><canvas id="c2" width="250" height="250"></canvas></div>
</div>
<script>
const S=25,GOAL=S*S-1,idx=(x,y)=>y*S+x;
const g=Array.from({length:S},()=>Array(S).fill(1));
g[0][0]=0;
const stack=[[0,0]];
while(stack.length){
const[cx,cy]=stack[stack.length-1];
const opts=[[2,0],[-2,0],[0,2],[0,-2]].map(d=>[cx+d[0],cy+d[1]]).filter(p=>p[0]>=0&&p[1]>=0&&p[0]<S&&p[1]<S&&g[p[1]][p[0]]===1);
if(opts.length){const[nx,ny]=opts[Math.random()*opts.length|0];g[ny][nx]=0;g[(cy+ny)/2][(cx+nx)/2]=0;stack.push([nx,ny]);}
else stack.pop();
}
function mk(id,type){
const a={type,name:["BFS","DFS","A*"][type],ctx:document.getElementById("c"+id).getContext("2d"),lb:document.getElementById("l"+id),open:[0],visited:new Uint8Array(S*S),parent:new Int16Array(S*S).fill(-1),gs:new Int32Array(S*S),done:false,path:[]};
a.visited[0]=1;
return a;
}
const algos=[mk(0,0),mk(1,1),mk(2,2)];
const fv=(a,n)=>a.gs[n]+(S-1-n%S)+(S-1-(n/S|0));
function step(a){
if(a.done||!a.open.length)return;
let n;
if(a.type===2){let bi=0;for(let i=1;i<a.open.length;i++)if(fv(a,a.open[i])<fv(a,a.open[bi]))bi=i;n=a.open.splice(bi,1)[0];}
else n=a.type===0?a.open.shift():a.open.pop();
if(n===GOAL){a.done=true;let p=n;while(p>=0){a.path.push(p);p=a.parent[p];}return;}
const x=n%S,y=n/S|0;
for(const d of[[1,0],[-1,0],[0,1],[0,-1]]){
const nx=x+d[0],ny=y+d[1];
if(nx<0||ny<0||nx>=S||ny>=S||g[ny][nx])continue;
const m=idx(nx,ny);
if(a.visited[m])continue;
a.visited[m]=1;a.parent[m]=n;a.gs[m]=a.gs[n]+1;a.open.push(m);
}
}
function draw(a){
const c=a.ctx;
for(let y=0;y<S;y++)for(let x=0;x<S;x++){
c.fillStyle=g[y][x]?"#1b1e26":a.visited[idx(x,y)]?"#2e6fae":"#dde3ea";
c.fillRect(x*10,y*10,10,10);
}
c.fillStyle="#ffd54a";
for(const n of a.path)c.fillRect(n%S*10,(n/S|0)*10,10,10);
c.fillStyle="#3fbf5f";c.fillRect(0,0,10,10);
c.fillStyle="#e05555";c.fillRect(240,240,10,10);
a.lb.textContent=a.done?a.name+" — DONE":a.name;
}
function loop(){
for(const a of algos)for(let k=0;k<3;k++)step(a);
for(const a of algos)draw(a);
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>▶ R25 · Sorting race quick/merge/heapOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sorting Race</title>
<style>
body{margin:0;background:#14171f;color:#eee;font-family:monospace;display:flex;justify-content:center;align-items:center;height:100vh}
.row{display:flex;gap:24px}
.p{text-align:center}
.lb{margin-bottom:6px;font-size:16px}
canvas{border:1px solid #444;background:#0d0f14}
</style>
</head>
<body>
<div class="row">
<div class="p"><div class="lb" id="l0">Quicksort</div><canvas id="c0" width="240" height="200"></canvas></div>
<div class="p"><div class="lb" id="l1">Mergesort</div><canvas id="c1" width="240" height="200"></canvas></div>
<div class="p"><div class="lb" id="l2">Heapsort</div><canvas id="c2" width="240" height="200"></canvas></div>
</div>
<script>
const N=60,base=[];
for(let i=0;i<N;i++)base.push(i+1);
for(let i=N-1;i>0;i--){const j=Math.random()*(i+1)|0,t=base[i];base[i]=base[j];base[j]=t;}
function recQuick(a,st){
const sw=(i,j)=>{const t=a[i];a[i]=a[j];a[j]=t;st.push([i,a[i]],[j,a[j]]);};
(function qs(lo,hi){
if(lo>=hi)return;
const p=a[hi];let i=lo;
for(let j=lo;j<hi;j++)if(a[j]<p)sw(i++,j);
sw(i,hi);qs(lo,i-1);qs(i+1,hi);
})(0,N-1);
}
function recMerge(a,st){
(function ms(lo,hi){
if(hi-lo<2)return;
const mid=(lo+hi)>>1;
ms(lo,mid);ms(mid,hi);
const tmp=[];let i=lo,j=mid;
while(i<mid||j<hi)tmp.push(j>=hi||(i<mid&&a[i]<=a[j])?a[i++]:a[j++]);
for(let k=0;k<tmp.length;k++){a[lo+k]=tmp[k];st.push([lo+k,tmp[k]]);}
})(0,N);
}
function recHeap(a,st){
const sw=(i,j)=>{const t=a[i];a[i]=a[j];a[j]=t;st.push([i,a[i]],[j,a[j]]);};
const sift=(i,n)=>{for(;;){let m=i;const l=2*i+1,r=l+1;if(l<n&&a[l]>a[m])m=l;if(r<n&&a[r]>a[m])m=r;if(m===i)break;sw(i,m);i=m;}};
for(let i=(N>>1)-1;i>=0;i--)sift(i,N);
for(let n=N-1;n>0;n--){sw(0,n);sift(0,n);}
}
function mk(id,name,rec){
const st=[];
rec(base.slice(),st);
return {name,st,pos:0,arr:base.slice(),hot:-1,done:false,ctx:document.getElementById("c"+id).getContext("2d"),lb:document.getElementById("l"+id)};
}
const panels=[mk(0,"Quicksort",recQuick),mk(1,"Mergesort",recMerge),mk(2,"Heapsort",recHeap)];
function draw(p){
const c=p.ctx;
c.fillStyle="#0d0f14";c.fillRect(0,0,240,200);
for(let i=0;i<N;i++){
const h=p.arr[i]*3;
c.fillStyle=p.done?"#3fbf5f":i===p.hot?"#e05555":"#4d9fe0";
c.fillRect(i*4,200-h,3,h);
}
p.lb.textContent=p.done?p.name+" — DONE":p.name;
}
function loop(){
for(const p of panels){
for(let k=0;k<2&&p.pos<p.st.length;k++){const s=p.st[p.pos++];p.arr[s[0]]=s[1];p.hot=s[0];}
if(p.pos>=p.st.length)p.done=true;
draw(p);
}
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>▶ R26 · Projectile ballisticsOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Projectile Motion</title>
<style>html,body{margin:0;height:100%;background:#0b1020;overflow:hidden}canvas{display:block}</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const cv=document.getElementById('c'),ctx=cv.getContext('2d');
let W,H,oy;const ox=60,G=280;
const angles=[20,34,45,60,75],cols=['#ff5252','#ffb300','#66bb6a','#29b6f6','#e040fb'];
let balls=[],waitT=0;
function launch(){const v0=Math.sqrt(0.85*(W-120)*G);
balls=angles.map((a,i)=>{const r=a*Math.PI/180;
return{x:ox,y:oy,vx:v0*Math.cos(r),vy:-v0*Math.sin(r),c:cols[i],ang:a,landed:false,lx:0};});
waitT=0;ctx.fillStyle='#0b1020';ctx.fillRect(0,0,W,H);}
function resize(){W=cv.width=innerWidth;H=cv.height=innerHeight;oy=H-60;launch();}
resize();addEventListener('resize',resize);
let last=performance.now();
function frame(t){requestAnimationFrame(frame);
const dt=Math.min((t-last)/1000,0.033);last=t;
ctx.fillStyle='rgba(11,16,32,0.05)';ctx.fillRect(0,0,W,H);
ctx.strokeStyle='#8899aa';ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(0,oy);ctx.lineTo(W,oy);ctx.stroke();
ctx.fillStyle='#cfd8dc';ctx.beginPath();ctx.arc(ox,oy,8,0,7);ctx.fill();
let all=true;
for(const b of balls){
if(!b.landed){all=false;b.vy+=G*dt;b.x+=b.vx*dt;b.y+=b.vy*dt;
if(b.y>=oy&&b.vy>0){b.y=oy;b.landed=true;b.lx=b.x;}}
ctx.fillStyle=b.c;ctx.beginPath();ctx.arc(b.x,b.y,6,0,7);ctx.fill();
if(b.landed){ctx.strokeStyle=b.c;ctx.lineWidth=2;
ctx.beginPath();ctx.moveTo(b.lx,oy);ctx.lineTo(b.lx,oy+14);ctx.stroke();
ctx.fillStyle=b.c;ctx.font='12px monospace';ctx.textAlign='center';
ctx.fillText(b.ang+'°',b.lx,oy+30);
ctx.fillText(Math.round((b.lx-ox)/10)+'m',b.lx,oy+44);}}
if(all){waitT+=dt;if(waitT>1.6)launch();}}
requestAnimationFrame(frame);
</script>
</body>
</html>▶ R27 · Double-pendulum chaosOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Double Pendulum Chaos</title>
<style>html,body{margin:0;height:100%;background:#05060f;overflow:hidden}canvas{display:block}</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const cv=document.getElementById('c'),ctx=cv.getContext('2d');
let W,H,L;function resize(){W=cv.width=innerWidth;H=cv.height=innerHeight;L=Math.min(W,H)*0.17;}
resize();addEventListener('resize',resize);
const m1=1,m2=1,g=9.81,l1=1,l2=1;
function deriv(s){const[a1,a2,w1,w2]=s,c=Math.cos(a1-a2),si=Math.sin(a1-a2),
den=2*m1+m2-m2*Math.cos(2*a1-2*a2);
return[w1,w2,
(-g*(2*m1+m2)*Math.sin(a1)-m2*g*Math.sin(a1-2*a2)-2*si*m2*(w2*w2*l2+w1*w1*l1*c))/(l1*den),
(2*si*(w1*w1*l1*(m1+m2)+g*(m1+m2)*Math.cos(a1)+w2*w2*l2*m2*c))/(l2*den)];}
function rk4(s,h){const k1=deriv(s),s2=s.map((v,i)=>v+h/2*k1[i]),k2=deriv(s2),
s3=s.map((v,i)=>v+h/2*k2[i]),k3=deriv(s3),s4=s.map((v,i)=>v+h*k3[i]),k4=deriv(s4);
return s.map((v,i)=>v+h/6*(k1[i]+2*k2[i]+2*k3[i]+k4[i]));}
const pend=[{s:[2.0,2.4,0,0],col:'#00e5ff',trail:[]},{s:[2.001,2.4,0,0],col:'#ff4081',trail:[]}];
function tip(s){const ax=W/2,ay=H*0.35;
const x1=ax+L*Math.sin(s[0]),y1=ay+L*Math.cos(s[0]);
return[x1,y1,x1+L*Math.sin(s[1]),y1+L*Math.cos(s[1]),ax,ay];}
let last=performance.now();
function frame(t){requestAnimationFrame(frame);
const dt=Math.min((t-last)/1000,0.033);last=t;
const n=Math.max(1,Math.round(dt/0.004));
for(const p of pend){for(let i=0;i<n;i++)p.s=rk4(p.s,dt*2/n);
const q=tip(p.s);p.trail.push([q[2],q[3]]);if(p.trail.length>2500)p.trail.shift();}
ctx.fillStyle='#05060f';ctx.fillRect(0,0,W,H);
for(const p of pend){ctx.strokeStyle=p.col;ctx.globalAlpha=0.55;ctx.lineWidth=1.2;
ctx.beginPath();p.trail.forEach((q,i)=>i?ctx.lineTo(q[0],q[1]):ctx.moveTo(q[0],q[1]));
ctx.stroke();ctx.globalAlpha=1;}
for(const p of pend){const[x1,y1,x2,y2,ax,ay]=tip(p.s);
ctx.strokeStyle=p.col;ctx.lineWidth=2.5;
ctx.beginPath();ctx.moveTo(ax,ay);ctx.lineTo(x1,y1);ctx.lineTo(x2,y2);ctx.stroke();
ctx.fillStyle=p.col;ctx.beginPath();ctx.arc(x1,y1,6,0,7);ctx.fill();
ctx.beginPath();ctx.arc(x2,y2,6,0,7);ctx.fill();}
ctx.fillStyle='#8899aa';ctx.beginPath();ctx.arc(W/2,H*0.35,4,0,7);ctx.fill();}
requestAnimationFrame(frame);
</script>
</body>
</html>▶ R28 · Particle fountainOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Particle Fountain</title>
<style>html,body{margin:0;height:100%;background:#070b14;overflow:hidden}canvas{display:block}
#ui{position:fixed;top:12px;left:12px;color:#cfd8dc;font:13px monospace;background:rgba(0,0,0,.45);padding:8px 12px;border-radius:8px;z-index:2}</style>
</head>
<body>
<div id="ui">Wind <input id="wind" type="range" min="-250" max="250" value="0" step="1"> <span id="wv">0</span></div>
<canvas id="c"></canvas>
<script>
const cv=document.getElementById('c'),ctx=cv.getContext('2d');
const slider=document.getElementById('wind'),wv=document.getElementById('wv');
let W,H;function resize(){W=cv.width=innerWidth;H=cv.height=innerHeight;}
resize();addEventListener('resize',resize);
const N=200,G=600,P=[];
function spawn(p,delay){p.x=W/2+(Math.random()-.5)*14;p.y=H-8;
p.vx=(Math.random()-.5)*90;p.vy=-(420+Math.random()*180);
p.hue=185+Math.random()*70;p.t=-(delay||0);}
for(let i=0;i<N;i++){const p={};spawn(p,i*0.012);P.push(p);}
let last=performance.now();
function frame(t){requestAnimationFrame(frame);
const dt=Math.min((t-last)/1000,0.033);last=t;
const wind=+slider.value;wv.textContent=wind;
ctx.fillStyle='rgba(7,11,20,0.28)';ctx.fillRect(0,0,W,H);
ctx.fillStyle='#22304a';ctx.fillRect(0,H-6,W,6);
for(const p of P){p.t+=dt;if(p.t<0)continue;
p.vy+=G*dt;p.vx+=wind*dt;p.x+=p.vx*dt;p.y+=p.vy*dt;
if(p.y>H-8){p.y=H-8;p.vy*=-0.55;p.vx*=0.75;
if(Math.abs(p.vy)<45){spawn(p,Math.random()*0.15);continue;}}
if(p.x<-30||p.x>W+30){spawn(p,Math.random()*0.15);continue;}
ctx.fillStyle='hsl('+p.hue+' 90% 65%)';
ctx.beginPath();ctx.arc(p.x,p.y,2.5,0,7);ctx.fill();}}
requestAnimationFrame(frame);
</script>
</body>
</html>▶ R29 · Orbital mechanicsOK★ 8.5/10 Open round →
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Orbital Mechanics</title>
<style>html,body{margin:0;height:100%;background:#020308;overflow:hidden}canvas{display:block}</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const cv=document.getElementById('c'),ctx=cv.getContext('2d');
let W,H,CX,CY,bodies=[];const GM=400000;
function init(){const s=Math.min(W,H)/560;bodies=[];
[[80,'#4fc3f7',4],[130,'#66bb6a',5],[190,'#ffb74d',6]].forEach(a=>{
const R=a[0]*s;bodies.push({x:CX+R,y:CY,vx:0,vy:Math.sqrt(GM/R),c:a[1],r:a[2]});});
const ra=250*s,rp=42*s,sa=(ra+rp)/2,v=Math.sqrt(GM*(2/ra-1/sa));
bodies.push({x:CX-ra,y:CY,vx:0,vy:-v,c:'#e0f7fa',r:3,comet:true});
ctx.fillStyle='#020308';ctx.fillRect(0,0,W,H);}
function resize(){W=cv.width=innerWidth;H=cv.height=innerHeight;CX=W/2;CY=H/2;init();}
resize();addEventListener('resize',resize);
let last=performance.now();
function frame(t){requestAnimationFrame(frame);
const dt=Math.min((t-last)/1000,0.033);last=t;
const steps=80,h=dt*2/steps;
for(const b of bodies)for(let i=0;i<steps;i++){
const dx=CX-b.x,dy=CY-b.y,d2=dx*dx+dy*dy,d=Math.sqrt(d2),a=GM/d2;
b.vx+=a*dx/d*h;b.vy+=a*dy/d*h;b.x+=b.vx*h;b.y+=b.vy*h;}
ctx.fillStyle='rgba(2,3,8,0.035)';ctx.fillRect(0,0,W,H);
const gr=ctx.createRadialGradient(CX,CY,2,CX,CY,26);
gr.addColorStop(0,'#fff8d0');gr.addColorStop(0.4,'#ffd54f');gr.addColorStop(1,'rgba(255,160,0,0)');
ctx.fillStyle=gr;ctx.beginPath();ctx.arc(CX,CY,26,0,7);ctx.fill();
for(const b of bodies){ctx.fillStyle=b.c;ctx.beginPath();ctx.arc(b.x,b.y,b.r,0,7);ctx.fill();
if(b.comet){const dx=b.x-CX,dy=b.y-CY,d=Math.hypot(dx,dy);
ctx.strokeStyle='rgba(224,247,250,0.5)';ctx.lineWidth=1;
ctx.beginPath();ctx.moveTo(b.x,b.y);ctx.lineTo(b.x+dx/d*18,b.y+dy/d*18);ctx.stroke();}}}
requestAnimationFrame(frame);
</script>
</body>
</html>▶ R30 · Spring-mass chainSTAT★ 8/10 Open round →
📝 chain settles correctly, anchor marked (8.0); drag not testable headless
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Spring-Mass Chain</title>
<style>html,body{margin:0;height:100%;background:#0a0e1a;overflow:hidden}canvas{display:block;cursor:grab}</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const cv=document.getElementById('c'),ctx=cv.getContext('2d');
let W,H,rest,drag=-1,mx=0,my=0;const N=12,masses=[];
function resize(){W=cv.width=innerWidth;H=cv.height=innerHeight;
const x0=W*0.08,x1=W*0.92;rest=(x1-x0)/(N-1);masses.length=0;
for(let i=0;i<N;i++)masses.push({x:x0+i*rest,y:H/2,vx:0,vy:0,fx:0,fy:0,fixed:i===0||i===N-1});}
resize();addEventListener('resize',resize);
cv.addEventListener('mousedown',e=>{let best=-1,bd=1600;
masses.forEach((m,i)=>{if(m.fixed)return;
const d=(m.x-e.clientX)**2+(m.y-e.clientY)**2;if(d<bd){bd=d;best=i;}});
if(best>=0){drag=best;mx=e.clientX;my=e.clientY;}});
addEventListener('mousemove',e=>{mx=e.clientX;my=e.clientY;});
addEventListener('mouseup',()=>drag=-1);
const K=1400,DAMP=6,M=1;
function physics(h){
for(const m of masses){m.fx=0;m.fy=0;}
for(let i=0;i<N-1;i++){const a=masses[i],b=masses[i+1];
const dx=b.x-a.x,dy=b.y-a.y,d=Math.hypot(dx,dy)||1e-6,ux=dx/d,uy=dy/d;
const rel=(b.vx-a.vx)*ux+(b.vy-a.vy)*uy;
const f=K*(d-rest)+DAMP*rel;
a.fx+=f*ux;a.fy+=f*uy;b.fx-=f*ux;b.fy-=f*uy;}
masses.forEach((m,i)=>{if(m.fixed)return;
if(i===drag){m.x=mx;m.y=my;m.vx=0;m.vy=0;return;}
m.vx=(m.vx+m.fx/M*h)*0.999;m.vy=(m.vy+m.fy/M*h)*0.999;
m.x+=m.vx*h;m.y+=m.vy*h;});}
let last=performance.now();
function frame(t){requestAnimationFrame(frame);
const dt=Math.min((t-last)/1000,0.033);last=t;
const steps=Math.max(1,Math.round(dt/0.002));
for(let i=0;i<steps;i++)physics(dt/steps);
ctx.fillStyle='#0a0e1a';ctx.fillRect(0,0,W,H);
ctx.strokeStyle='#5c7cfa';ctx.lineWidth=2;
for(let i=0;i<N-1;i++){ctx.beginPath();ctx.moveTo(masses[i].x,masses[i].y);
ctx.lineTo(masses[i+1].x,masses[i+1].y);ctx.stroke();}
masses.forEach((m,i)=>{ctx.beginPath();ctx.arc(m.x,m.y,i===drag?13:9,0,7);
ctx.fillStyle=m.fixed?'#546e7a':i===drag?'#ffca28':'#90caf9';ctx.fill();
if(i===drag){ctx.strokeStyle='#fff';ctx.lineWidth=2;ctx.stroke();
ctx.strokeStyle='#5c7cfa';}});}
requestAnimationFrame(frame);
</script>
</body>
</html>Answer excerpts above cover R6–R30. Classic rounds R1–R5 live on their own round pages and aren't duplicated here.








