Skip to content

Instantly share code, notes, and snippets.

@blakek
Created March 3, 2023 02:13
Show Gist options
  • Save blakek/ecddc61d47ad3d5b242b1d0778795378 to your computer and use it in GitHub Desktop.
Save blakek/ecddc61d47ad3d5b242b1d0778795378 to your computer and use it in GitHub Desktop.
7th grader homework checker - TypeScript functions that can be used to calculate the area and perimeter of a circle
const PI = 3.14;
const CircleSize = {
Quarter: 0.25,
Half: 0.5,
Full: 1,
};
type WithRadiusOrDiameter = { r?: number; d?: number };
type WithPercent = { percent: typeof CircleSize[keyof typeof CircleSize] };
type AreaOptions = WithRadiusOrDiameter & WithPercent;
type PerimeterOptions = WithRadiusOrDiameter & WithPercent;
type SolveOptions = WithRadiusOrDiameter &
WithPercent & {
area?: number;
perimeter?: number;
};
function areaOfCircle(options: AreaOptions) {
let radius = options.r ?? options.d! / 2;
let percent = options.percent ?? CircleSize.Full;
if (!radius) {
throw new Error("Radius or diameter is required");
}
return PI * radius ** 2 * percent;
}
function perimeterOfCircle(options: PerimeterOptions) {
let radius = options.r ?? options.d! / 2;
let percent = options.percent ?? CircleSize.Full;
if (!radius) {
throw new Error("Radius or diameter is required");
}
const fullPerimeter = 2 * PI * radius;
if (percent === CircleSize.Full) {
return fullPerimeter;
}
return fullPerimeter * percent + 2 * radius;
}
function printAnswer(options: Required<SolveOptions>): void {
for (const k of Object.keys(options)) {
const key = k as keyof typeof options;
if (typeof options[key] === "number") {
options[key] = Number(options[key].toFixed(2));
}
}
console.table(options);
}
function solve(options: SolveOptions): any {
if (options.r) {
return printAnswer({
area: areaOfCircle(options),
d: options.r * 2,
r: options.r,
perimeter: perimeterOfCircle(options),
percent: options.percent ?? CircleSize.Full,
});
}
if (options.d) {
return printAnswer({
area: areaOfCircle(options),
d: options.d,
r: options.d / 2,
perimeter: perimeterOfCircle(options),
percent: options.percent ?? CircleSize.Full,
});
}
if (options.area) {
const r = Math.sqrt(options.area / (PI * options.percent));
return solve({ ...options, r });
}
if (options.perimeter) {
let r: number;
if (options.percent === CircleSize.Full) {
r = options.perimeter / (2 * PI);
} else {
r = options.perimeter / (2 * PI * options.percent + 2);
}
return solve({ ...options, r });
}
throw new Error("No options provided");
}
// solve({
// percent: CircleSize.Quarter,
// perimeter: 57.12
// });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment