Skip to content

Instantly share code, notes, and snippets.

@kerryboyko
Created September 17, 2023 21:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kerryboyko/cd6dda9b3da81992abd4214fdf9e5ec0 to your computer and use it in GitHub Desktop.
Save kerryboyko/cd6dda9b3da81992abd4214fdf9e5ec0 to your computer and use it in GitHub Desktop.
FloatBuzz
import { floatBuzz, naiveFloatBuzz, coerceFloatToRatio, Ratio} from './floatBuzz';
test('NaiveFloatBuzz', () => {
expect(naiveFloatBuzz(0.3)).toBe("Float");
expect(naiveFloatBuzz(0.6)).toBe("Float");
expect(naiveFloatBuzz(0.9)).not.toBe("Float"); // this will fail using the naive approach.
expect(naiveFloatBuzz(1.2)).toBe("Float");
expect(naiveFloatBuzz(0.5)).toBe("Buzz");
expect(naiveFloatBuzz(1.0)).toBe("Buzz");
expect(naiveFloatBuzz(2.0)).toBe("Buzz");
expect(naiveFloatBuzz(2.5)).toBe("Buzz");
expect(naiveFloatBuzz(1.5)).toBe("FloatBuzz!");
expect(naiveFloatBuzz(3.0)).toBe("FloatBuzz!");
expect(naiveFloatBuzz(4.5)).toBe("FloatBuzz!");
expect(naiveFloatBuzz(6.0)).toBe("FloatBuzz!");
})
test('floats', () => {
expect(floatBuzz(0.1)).toBe(0.1);
})
test('Float', () => {
expect(floatBuzz(0.3)).toBe("Float");
expect(floatBuzz(0.6)).toBe("Float");
expect(floatBuzz(0.9)).toBe("Float"); // this will fail using the naive approach.
expect(floatBuzz(1.2)).toBe("Float");
})
test('Buzz', () => {
expect(floatBuzz(0.5)).toBe("Buzz");
expect(floatBuzz(1.0)).toBe("Buzz");
expect(floatBuzz(2.0)).toBe("Buzz");
expect(floatBuzz(2.5)).toBe("Buzz");
})
test('FloatBuzz!', () => {
expect(floatBuzz(1.5)).toBe("FloatBuzz!");
expect(floatBuzz(3.0)).toBe("FloatBuzz!");
expect(floatBuzz(4.5)).toBe("FloatBuzz!");
expect(floatBuzz(6.0)).toBe("FloatBuzz!");
})
test("Ratio class", () => {
const r = new Ratio(1, 2);
expect(r.numerator).toBe(1);
expect(r.denominator).toBe(2);
expect(r.value).toBe(0.5);
})
test('coerceFloatToRatio', () => {
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((el) => coerceFloatToRatio(el)).forEach((ratio) => {-
expect(ratio.denominator).toBe(100);
})
})
test('allTogetherNow', () => {
const m: number[] = [];
for(let i = 0; i <= 100000; i++){
const f = i / 10;
m.push(f);
}
const control = m.map((el, i) => {
if(i % 15 === 0){
return "FloatBuzz!"
}
if(i % 5 === 0){
return "Buzz";
}
if(i % 3 == 0){
return "Float"
}
return el;
})
m.forEach((el, i) => {
const test = floatBuzz(el);
if(test !== control[i]){
console.log(`control: ${control[i]}, test: ${test}`)
console.log(coerceFloatToRatio(el))
}
})
expect(m.map((el) => floatBuzz(el))).toEqual(control);
})
export class Ratio {
constructor(public numerator: number, public denominator: number){
}
get value (): number {
return this.numerator/this.denominator;
}
}
export const coerceFloatToRatio = (float: number, precision: number = 2): any => {
const divisor = Math.pow(10, precision);
return new Ratio(Math.round(float * divisor), divisor)
}
/* THIS NAIVE SOLUTION WILL NOT WORK */
export const naiveFloatBuzz = (float: number): number | string => {
if(float % 1.5 === 0){
return "FloatBuzz!"
}
if(float % 0.5 === 0){
return "Buzz";
}
if(float % 0.3 === 0){
return "Float";
}
return float;
}
/* THIS SLIGHTLY MORE COMPLEX SOLUTION WILL */
export const floatBuzz = (input: number, precision: number = 5): number | string => {
const rFloat = coerceFloatToRatio(0.3, precision);
const rBuzz = coerceFloatToRatio(0.5, precision);
const rFloatBuzz = coerceFloatToRatio(1.5, precision);
const rInput = coerceFloatToRatio(input, precision);
// console.log(rInput)
if(rInput.numerator % rFloatBuzz.numerator === 0){
return "FloatBuzz!"
}
if(rInput.numerator % rBuzz.numerator === 0){
return "Buzz";
}
if(rInput.numerator % rFloat.numerator === 0){
return "Float";
}
return input;
}export class Ratio {
constructor(public numerator: number, public denominator: number){
}
get value (): number {
return this.numerator/this.denominator;
}
}
export const coerceFloatToRatio = (float: number, precision: number = 2): any => {
const divisor = Math.pow(10, precision);
return new Ratio(Math.round(float * divisor), divisor)
}
/* THIS NAIVE SOLUTION WILL NOT WORK */
export const naiveFloatBuzz = (float: number): number | string => {
if(float % 1.5 === 0){
return "FloatBuzz!"
}
if(float % 0.5 === 0){
return "Buzz";
}
if(float % 0.3 === 0){
return "Float";
}
return float;
}
/* THIS SLIGHTLY MORE COMPLEX SOLUTION WILL */
export const floatBuzz = (input: number, precision: number = 5): number | string => {
const rFloat = coerceFloatToRatio(0.3, precision);
const rBuzz = coerceFloatToRatio(0.5, precision);
const rFloatBuzz = coerceFloatToRatio(1.5, precision);
const rInput = coerceFloatToRatio(input, precision);
// console.log(rInput)
if(rInput.numerator % rFloatBuzz.numerator === 0){
return "FloatBuzz!"
}
if(rInput.numerator % rBuzz.numerator === 0){
return "Buzz";
}
if(rInput.numerator % rFloat.numerator === 0){
return "Float";
}
return input;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment