1. Warm-Up: Typing Practice
Improve your typing speed and accuracy here: Typeracer
2. Core Challenge: Spinning Donut in C
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main() {
float A = 0, B = 0, i, j;
const float R1 = 1; // inner radius
const float R2 = 2; // outer radius
const float K2 = 5; // distance from viewer to donut center
// Terminal size
const int width = 80;
const int height = 24;
// Scaling factor: lower K1 → smaller donut
const float K1 = width * K2 * 3 / (16 * (R1 + R2));
float z[width * height];
char b[width * height + 1];
b[width*height] = '\0';
while (1) {
memset(b, ' ', width * height);
memset(z, 0, sizeof(z));
for (j = 0; j < 2 * M_PI; j += 0.07) {
for (i = 0; i < 2 * M_PI; i += 0.02) {
float cosj = cosf(j), sinj = sinf(j);
float cosi = cosf(i), sini = sinf(i);
float cosA = cosf(A), sinA = sinf(A);
float cosB = cosf(B), sinB = sinf(B);
float circlex = R2 + R1 * cosi;
float circley = R1 * sini;
float x = circlex * (cosB * cosj + sinA * sinB * sinj)
- circley * cosA * sinB;
float y = circlex * (sinB * cosj - sinA * cosB * sinj)
+ circley * cosA * cosB;
float zval = circlex * (cosA * cosj * sinB - sinA * sinj)
+ circley * sinA * cosj
+ K2;
float ooz = 1.0f / zval;
int xp = (int)(width / 2 + K1 * ooz * x);
int yp = (int)(height / 2 - K1 * ooz * y);
int idx = xp + yp * width;
float L = cosj * cosi * sinB
- cosA * cosi * sinj
- sinA * sini
+ cosB * (cosA * sini - sinA * cosi * sinj);
if (xp >= 0 && xp < width && yp >= 0 && yp < height && ooz > z[idx]) {
z[idx] = ooz;
int lum = (int)(L * 8.0f);
if (lum < 0) lum = 0;
if (lum > 11) lum = 11;
b[idx] = ".,-~:;=!*#$@"[lum];
}
}
}
printf("\x1b[H");
for (int k = 0; k < width * height; k++) {
putchar(k % width ? b[k] : '\n');
}
A += 0.04f;
B += 0.02f;
usleep(30000);
}
return 0;
}
Reference: Donut Math Explanation