Unicode Fractions

21

2

Given a fraction in the format m/n (where m and n are coprime integers), output the corresponding Unicode fraction. Your program/function will not be expected to take in any input that does not correspond to a Unicode character. Arrays, e.g. [2, 3] as opposed to 2/3, are accepted. m / n as opposed to m/n is also fine. Two separate inputs m and n are also valid.

The Unicode fractions that must be handled are as follows:

½, ⅓, ⅔, ¼, ¾, ⅕, ⅖, ⅗, ⅘, ⅙, ⅚, ⅐, ⅛, ⅜, ⅝, ⅞, ⅑, ⅒

Thus, the possible inputs are as follows:

1/2, 1/3, 2/3, 1/4, 3/4, 1/5, 2/5, 3/5, 4/5, 1/6, 5/6, 1/7, 1/8, 3/8, 5/8, 7/8, 1/9, 1/10

The Unicode codepoints of the characters are as follows:

188 ¼
189 ½
190 ¾
8528 ⅐
8529 ⅑
8530 ⅒
8531 ⅓
8532 ⅔
8533 ⅕
8534 ⅖
8535 ⅗
8536 ⅘
8537 ⅙
8538 ⅚
8539 ⅛
8540 ⅜
8541 ⅝
8542 ⅞

Test Cases

1/2 -> ½
1/3 -> ⅓
2/3 -> ⅔
1/4 -> ¼
3/4 -> ¾
3/8 -> ⅜
1/10 -> ⅒

Make your code as short as possible; this is code golf.

0WJYxW9FMN

Posted 2017-12-16T15:00:01.500

Reputation: 2 663

Can you add the unicode code points for each fraction? – Rod – 2017-12-16T15:05:52.053

4188 ¼, 189 ½, 190 ¾, 8528 ⅐, 8529 ⅑, 8530 ⅒, 8531 ⅓, 8532 ⅔, 8533 ⅕, 8534 ⅖, 8535 ⅗, 8536 ⅘, 8537 ⅙, 8538 ⅚, 8539 ⅛, 8540 ⅜, 8541 ⅝, 8542 ⅞ – Leaky Nun – 2017-12-16T15:14:06.850

You will not be expected to allow any input that does not correspond to a unicode character. Does that mean that we must detect invalid inputs? Or that this is not supposed to happen? – Arnauld – 2017-12-16T15:31:48.320

@Arnauld The latter one. – user202729 – 2017-12-16T15:32:41.280

Can the input be an object that represents a fraction? – Brad Gilbert b2gills – 2017-12-16T17:33:39.577

@BradGilbertb2gills What, something like a list? – 0WJYxW9FMN – 2017-12-16T18:45:48.037

Perl 6 has Rational types which have a numerator and denominator.

– Brad Gilbert b2gills – 2017-12-16T19:29:02.647

@BradGilbertb2gills Oh, I understand now; thanks! Yes, those are definitely allowed. – 0WJYxW9FMN – 2017-12-16T21:54:08.593

Answers

14

JavaScript (Node.js), 78 77 bytes

Saved 1 byte thanks to @HermanLauenstein

Takes input in currying syntax (m)(n).

m=>n=>'¾⅗  ⅜    ⅞⅘½⅓¼⅕⅙⅐⅛⅑⅒⅚⅔⅝⅖'[(m*9+n)%31]

Try it online!

Arnauld

Posted 2017-12-16T15:00:01.500

Reputation: 111 334

@user202729 I'm sure I used a similar formula elsewhere. I don't remember for which challenge, though. Now, it might be worth trying to generate the characters with String.fromCharCode(), but I'd expect a similar byte count. – Arnauld – 2017-12-16T15:43:45.843

-1 byte – Herman L – 2017-12-16T16:35:36.563

@HermanLauenstein Thanks! (I missed that one because I was initially just looking for the smallest modulo. I had already switched to the XOR method when I started removing trailing empty slots.) – Arnauld – 2017-12-16T16:44:09.570

And if you post your answer too soon, it will make people to mostly use your approach... – user202729 – 2017-12-17T03:14:09.540

12

Perl 6,  48  43 bytes

{chr first *.unival==$^m/$^n,(|^191,|(8528..*))}

Try it

{chr first *.unival==$_,(|^191,|(8528..*))}

Try it

Expanded:

{  # bare block lambda with implicit parameter 「$_」
  chr

    first               # find the first value

      *.unival ==       # which has a unicode value that matches
          $_,           # the input fraction (as a Rational)

      (
        |^191,     # ¼(189) ½(188) ¾(190)
        |(8528..*) # all of the rest
      )
}

Note that the search has to be split up so that it doesn't return other Unicode characters that have the same unival. (otherwise it would be (1..*))

Brad Gilbert b2gills

Posted 2017-12-16T15:00:01.500

Reputation: 12 713

3

Wait, Perl 6 has a built-in for this exact thing?

– Erik the Outgolfer – 2017-12-16T20:14:15.953

2@EriktheOutgolfer I’m not sure that that’s quite how to look at it, but yes, you can access the code point's numeric value reflected in the 9th column from the Unicode Character Database in the file UnicodeData.txt. For example, U+109BC MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS has the character property nv=11/12. There are some 1500 code points with non-empty numeric values—rather more than this small challenge asks one to solve for. These are whole numbers or rationals. – tchrist – 2017-12-17T04:41:50.043

7

APL (Dyalog), 88 64 bytes

{⎕UCS(⌊(⍺-1)÷(1+⍵≡8)⌈4×⍵≡6)-(291194049⊤⍨10⌿12)[⍵]-189⌈8539××⍵|4}

Try it online!

-3 thanks to dzaima.

Using ETHproductions's 84-byte approach.

The f← included on TIO isn't counted, since it's put there just to be able to test the function.

Erik the Outgolfer

Posted 2017-12-16T15:00:01.500

Reputation: 38 134

7

JavaScript (ES6), 88 86 84 81 79 bytes

Saved 2 bytes thanks to @Arnauld

m=>n=>String.fromCharCode((4%n?8528:188)|"  130470912"[n]*1.3+~-m/-~"3 1"[n-6])

Not quite as short as the other JS answer, but it was fun to calculate the code-point of each fraction mathematically.

Test snippet

let f =
m=>n=>String.fromCharCode((4%n?8528:188)|"  130470912"[n]*1.3+~-m/-~(n-6?n==8:3))

document.body.innerText = [
  [1,2],
  [1,3], [2,3],
  [1,4], [3,4],
  [1,5], [2,5], [3,5], [4,5],
  [1,6], [5,6],
  [1,7],
  [1,8], [3,8], [5,8], [7,8],
  [1,9],
  [1,10]
].map(([m,n])=>m+"/"+n+": "+f(m)(n)).join('\n')

Old method (82 bytes):

m=>n=>String.fromCharCode((4%n?8539:189)-("0x"+"  08162b0a9"[n])+~-m/-~"3 1"[n-6])

Saved 4 bytes on this one thanks to @Arnauld.

ETHproductions

Posted 2017-12-16T15:00:01.500

Reputation: 47 880

1-2 bytes on both versions with -~'3 1'[n-6] – Arnauld – 2017-12-16T21:07:30.730

2

SOGL V0.12, 51 bytes

5*+'æ%'⁵%"∫}ΣS“LI─{"#!“+ζ}¹"¾ŗŗŗŗŗŗ⅛ŗ⅜½⅝ŗ⅞ ⅓⅔ŗ  ¼”W

Try it Here!

uses the mapping (m + n*5)%33%22

Explanation:

5*                        multiply the 1st input by 5
  +                       add to the 2nd input
   'æ%                    modulo 33
      '⁵%                 module 22

"∫}ΣS“                    push 2153527158
      LI─                 base 11 decode that - [10 0 5 6 7 8 9 1 2]
         {     }          for each of that
          "#!“+             add 8528
               ζ            and convert to a character
                "...”     push "¾ŗŗŗŗŗŗ⅛ŗ⅜½⅝ŗ⅞ ⅓⅔ŗ  ¼", replacing ŗ with each character of the above array
                     W    and get the (m + n*5)%33%22th item from that

dzaima

Posted 2017-12-16T15:00:01.500

Reputation: 19 048

2

Clojure, 127 bytes

(comp{2/3\⅔ 4/5\⅘ 1/3\⅓ 1/2\½ 5/6\⅚ 1/5\⅕ 1/4\¼ 3/5\⅗ 1/7\⅐ 3/4\¾ 2/5\⅖ 1/6\⅙ 1/9\⅑ 1/8\⅛ 3/8\⅜ 1/10\⅒ 5/8\⅝ 7/8\⅞}read-string)

An anonymous function that takes input as "1/2", and returns the corresponding character.

A straight mapping from a Clojure Ratio to a fraction character. comp, and the fact that Clojure maps are functions really helped here. I needed to pass the string input through read-string to evaluate it as a ratio type, since that allows me to discard all the bloating quotes in the map. comp let me do that point-free, which was nice. The "full" code would be:

(defn to-unicode-fraction [frac]
  (get {2/3\⅔ 4/5\⅘ 1/3\⅓ 1/2\½ 5/6\⅚ 1/5\⅕ 1/4\¼ 3/5\⅗ 1/7\⅐,
        3/4\¾ 2/5\⅖ 1/6\⅙ 1/9\⅑ 1/8\⅛ 3/8\⅜ 1/10\⅒ 5/8\⅝ 7/8\⅞}
       (read-string frac)))

After looking over the other answers, I realized that this approach is pretty naïve. I'm looking for ways of improving it.

Carcigenicate

Posted 2017-12-16T15:00:01.500

Reputation: 3 295

1

Swift, 106 82 bytes

Port of @Arnaulds JavaScript answer

Saved 24 bytes thanks to @Mr.Xcoder

{Array("¾⅗  ⅜    ⅞⅘½⅓¼⅕⅙⅐⅛⅑⅒⅚⅔⅝⅖")[($0*9+$1)%31]}

Try it online!

Herman L

Posted 2017-12-16T15:00:01.500

Reputation: 3 611

Use closures for 82 bytes (you don’t have to include var f= in the byte count)

– Mr. Xcoder – 2017-12-16T17:13:30.960

1

Charcoal, 77 48 46 bytes

F§§⪪“YW³⦄Eν~vγ@⊖Xμ~?Iw⸿M➙b℅¦⦃”,NN℅⁺℅ι×⁹⁰∨№βι⁹⁴

Try it online! Link is to verbose version of code. Edit: Saved 29 31 bytes by mapping from ASCII chars to multibyte chars. Explanation:

    “....”                  Compressed string `R,EFcGbIMDO,H J,K  Pd,L,N Q,`
   ⪪      ,                 Split on commas
           N                First input
  §                         Circularly index
            N               Second input
 §                          Circularly index
F                           "Loop over" character (loop variable `i`)
                     №βι    Count of `i`s in lowercase letters
                    ∨   ⁹⁴  Replace zero result with 94
                 ×⁹⁰        Multiply by 90
               ℅ι           Take ordinal of `i`
              ⁺             Sum
             ℅              Convert back to character
                            Implicitly print

Neil

Posted 2017-12-16T15:00:01.500

Reputation: 95 035

0

Python 3, 97 bytes

lambda m,n:'½ ⅓⅔ ¼_¾ ⅕⅖⅗⅘ ⅙___⅚ ⅐ ⅛_⅜_⅝_⅞ ⅑ ⅒'.split()[n-2][m-1]

Ryan McCampbell

Posted 2017-12-16T15:00:01.500

Reputation: 41

2This doesn't seem to work, you need [n-2][m-1] instead. – Erik the Outgolfer – 2017-12-16T17:21:11.260

Right, I guess I didn't test it first... – Ryan McCampbell – 2017-12-17T22:18:11.713

0

Python 3, 87 bytes

lambda n:'⅛⅑⅜¾⅗⅔⅚⅖⅝⅘⅞⅒½⅓¼⅕⅙⅐'[int(n[::2])%50%36%31%18]

Try it online!

or

lambda n:'⅝⅔⅜⅖__⅞¾⅗⅘_⅒½⅓¼⅕⅙⅐⅛⅑⅚'[int(n[::2])%36%27%22]

Try it online!

ovs

Posted 2017-12-16T15:00:01.500

Reputation: 21 408

0

Vim Script, 67 bytes

fu!F(m,n)
if a:n==10|norm a⅒ 
else|exe'norm a'.a:m.a:n
endif
endfu

The function works with Vim's digraphs which are entered after starting them iwth ctrl-k. Apparently, the relevant ctrl-k character after the exe'norm is not rendered in the code block above.

René Nyffenegger

Posted 2017-12-16T15:00:01.500

Reputation: 101