Created
September 17, 2023 21:45
-
-
Save kerryboyko/cd6dda9b3da81992abd4214fdf9e5ec0 to your computer and use it in GitHub Desktop.
FloatBuzz
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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