From e28d7d0d8ce6601073c873ddc653723df90be84d Mon Sep 17 00:00:00 2001 From: Vlad Pronsky Date: Thu, 1 Jun 2023 18:31:48 +0300 Subject: [PATCH] add unicode printer --- readme.md | 16 +++++++++++ src/main.test.ts | 73 +++++++++++++++++++++++++++++++++-------------- src/main.ts | 74 ++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 137 insertions(+), 26 deletions(-) diff --git a/readme.md b/readme.md index 3377939..72ce502 100644 --- a/readme.md +++ b/readme.md @@ -137,3 +137,19 @@ fraq(1, 2).eq([1, 3]) // -> false ### `.gt(b: Fraq) -> boolean` ### `.gte(b: Fraq) -> boolean` + +### `.toAscii(limit=16)` + +```typescript +fraq(0.5).toUnicode() // -> "1/2" +fraq(1, 64).toUnicode() // -> "0" +fraq(1, 64).toUnicode(64) // -> "1/64" +``` + +### `.toUnicode()` + +```typescript +fraq(0.5).toUnicode() // -> "½" +fraq(1, 64).toUnicode() // -> "0" +fraq(1, 64).toUnicode(64) // -> "¹⁄₆₄" +``` diff --git a/src/main.test.ts b/src/main.test.ts index 63d77b2..bd1c82c 100644 --- a/src/main.test.ts +++ b/src/main.test.ts @@ -44,10 +44,15 @@ test("should create fraction", () => { equal(fraq(2).toPair(), [2, 1]) equal(fraq(new Fraction(2)).toPair(), [2, 1]) - equal(fraq(0.5).toPair(), [1, 2]) - equal(fraq(1.5).toPair(), [3, 2]) - equal(fraq(-0.5).toPair(), [-1, 2]) - equal(fraq(-1.5).toPair(), [-3, 2]) + equal(fraq(0.5).toPair(), [5, 10]) + equal(fraq(1.5).toPair(), [15, 10]) + equal(fraq(-0.5).toPair(), [-5, 10]) + equal(fraq(-1.5).toPair(), [-15, 10]) + + equal(fraq(0.5).reduce().toPair(), [1, 2]) + equal(fraq(1.5).reduce().toPair(), [3, 2]) + equal(fraq(-0.5).reduce().toPair(), [-1, 2]) + equal(fraq(-1.5).reduce().toPair(), [-3, 2]) }) test("should abs fraction", () => { @@ -213,14 +218,14 @@ test("should parse from string", () => { equal(fraq("2 9/3").reduce().toPair(), [5, 1]) equal(fraq("3 27/9").reduce().toPair(), [6, 1]) - equal(fraq("0.5").toPair(), [1, 2]) - equal(fraq("1.5").toPair(), [3, 2]) - equal(fraq("-0.5").toPair(), [-1, 2]) - equal(fraq("-1.5").toPair(), [-3, 2]) - equal(fraq(".5").toPair(), [1, 2]) - equal(fraq("-.5").toPair(), [-1, 2]) - equal(fraq(".0").toPair(), [0, 1]) - equal(fraq("-.0").toPair(), [0, 1]) + equal(fraq("0.5").reduce().toPair(), [1, 2]) + equal(fraq("1.5").reduce().toPair(), [3, 2]) + equal(fraq("-0.5").reduce().toPair(), [-1, 2]) + equal(fraq("-1.5").reduce().toPair(), [-3, 2]) + equal(fraq(".5").reduce().toPair(), [1, 2]) + equal(fraq("-.5").reduce().toPair(), [-1, 2]) + equal(fraq(".0").reduce().toPair(), [0, 1]) + equal(fraq("-.0").reduce().toPair(), [0, 1]) equal(fraq("1.33").toPair(), [133, 100]) equal(fraq("1.333").toPair(), [1333, 1000]) @@ -258,10 +263,6 @@ test("should print to ascii", () => { equal(fraq("1/-2").toAscii(), "-1/2") equal(fraq("1.0").toAscii(), "1") - for (let i = 1; i < 16; ++i) { - equal(fraq(`${i}/16`).toAscii(), `${i}/16`) - } - // equal(fraq(".0625").toAscii(), "5/8") // equal(fraq(".083").toAscii(), "5/6") // equal(fraq(".1875").toAscii(), "1/5") @@ -288,21 +289,51 @@ test("should print to ascii", () => { equal(fraq(".125").toAscii(), "1/8") equal(fraq(".143").toAscii(), "1/7") equal(fraq(".166").toAscii(), "1/6") - equal(fraq(".2").toAscii(), "1/5") + equal(fraq(".2").reduce().toAscii(), "1/5") equal(fraq(".25").toAscii(), "1/4") equal(fraq(".3").toAscii(), "3/10") equal(fraq(".33").toAscii(), "1/3") equal(fraq(".375").toAscii(), "3/8") - equal(fraq(".4").toAscii(), "2/5") - equal(fraq(".5").toAscii(), "1/2") - equal(fraq(".6").toAscii(), "3/5") + equal(fraq(".4").reduce().toAscii(), "2/5") + equal(fraq(".5").reduce().toAscii(), "1/2") + equal(fraq(".6").reduce().toAscii(), "3/5") equal(fraq(".625").toAscii(), "5/8") equal(fraq(".66").toAscii(), "2/3") equal(fraq(".7").toAscii(), "7/10") equal(fraq(".75").toAscii(), "3/4") - equal(fraq(".8").toAscii(), "4/5") + equal(fraq(".8").reduce().toAscii(), "4/5") equal(fraq(".875").toAscii(), "7/8") equal(fraq(".9").toAscii(), "9/10") + + equal(fraq("1/64").toAscii(64), "1/64") + equal(fraq("1 1/64").toAscii(64), "1 1/64") + equal(fraq("1 1/64").toAscii(), "1") +}) + +test("should print to unicode", () => { + equal(fraq("0").toUnicode(), "0") + equal(fraq("1").toUnicode(), "1") + equal(fraq("2").toUnicode(), "2") + equal(fraq("-0").toUnicode(), "0") + equal(fraq("-1").toUnicode(), "-1") + equal(fraq("-2").toUnicode(), "-2") + + equal(fraq("1/1").toUnicode(), "1") + equal(fraq("1/2").toUnicode(), "½") + equal(fraq("1/3").toUnicode(), "⅓") + equal(fraq("3/2").toUnicode(), "1½") + equal(fraq("3/4").toUnicode(), "¾") + equal(fraq("-1/2").toUnicode(), "-½") + equal(fraq("1/-2").toUnicode(), "-½") + equal(fraq("1.0").toUnicode(), "1") + + equal(fraq("1.75").toUnicode(), "1¾") + equal(fraq("-1.75").toUnicode(), "-1¾") + equal(fraq("-.75").toUnicode(), "-¾") + + equal(fraq("1/64").toUnicode(64), "¹⁄₆₄") + equal(fraq("1 1/64").toUnicode(64), "1¹⁄₆₄") + equal(fraq("1 1/64").toUnicode(), "1") }) test.run() diff --git a/src/main.ts b/src/main.ts index 1f38a97..846ea27 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,3 +1,50 @@ +const UniNumber: Record = { + "1/10": "⅒", + "1/2": "½", + "1/3": "⅓", + "1/4": "¼", + "1/5": "⅕", + "1/6": "⅙", + "1/7": "⅐", + "1/8": "⅛", + "1/9": "⅑", + "2/3": "⅔", + "2/5": "⅖", + "3/4": "¾", + "3/5": "⅗", + "3/8": "⅜", + "4/5": "⅘", + "5/6": "⅚", + "5/8": "⅝", + "7/8": "⅞", +} + +const SupNumber: Record = { + "0": "⁰", + "1": "¹", + "2": "²", + "3": "³", + "4": "⁴", + "5": "⁵", + "6": "⁶", + "7": "⁷", + "8": "⁸", + "9": "⁹", +} + +const SubNumber: Record = { + "0": "₀", + "1": "₁", + "2": "₂", + "3": "₃", + "4": "₄", + "5": "₅", + "6": "₆", + "7": "₇", + "8": "₈", + "9": "₉", +} + /** * Most of this file is rewritten from the Python Standard Library * Regards to Sjoerd Mullender & Jeffrey Yasskin @@ -267,13 +314,30 @@ export class Fraction { return n === 0 ? { s, c: 0, n: c, d } : { s, c, n, d } } - toAscii(): string { - let t: Fraction - t = this.limit(16) - - const p = t.toParts() + toAscii(limit = 16): string { + let p = this.reduce().limit(limit).toParts() if (p.d === 1) return `${p.s * p.n}` if (p.c === 0) return `${p.s * p.n}/${p.d}` return `${p.s * p.c} ${p.n}/${p.d}` } + + toUnicode(limit = 16): string { + let p = this.reduce().limit(limit).toParts() + if (p.d === 1) return `${p.s * p.n}` + + let t: string + const x = `${p.n}/${p.d}` + if (x in UniNumber) t = UniNumber[x] + else { + // prettier-ignore + const nt = p.n.toString().split("").map(c => SupNumber[c]).join("") + // prettier-ignore + const dt = p.d.toString().split("").map(c => SubNumber[c]).join("") + + t = `${nt}⁄${dt}` + } + + const st = p.s === -1 ? "-" : "" + return p.c === 0 ? `${st}${t}` : `${st}${p.c}${t}` + } }