21
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Can you add the unicode code points for each fraction? \$\endgroup\$ – Rod Dec 16 '17 at 15:05
  • 4
    \$\begingroup\$ 188 ¼, 189 ½, 190 ¾, 8528 ⅐, 8529 ⅑, 8530 ⅒, 8531 ⅓, 8532 ⅔, 8533 ⅕, 8534 ⅖, 8535 ⅗, 8536 ⅘, 8537 ⅙, 8538 ⅚, 8539 ⅛, 8540 ⅜, 8541 ⅝, 8542 ⅞ \$\endgroup\$ – Leaky Nun Dec 16 '17 at 15:14
  • \$\begingroup\$ 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? \$\endgroup\$ – Arnauld Dec 16 '17 at 15:31
  • \$\begingroup\$ @Arnauld The latter one. \$\endgroup\$ – user202729 Dec 16 '17 at 15:32
  • \$\begingroup\$ Can the input be an object that represents a fraction? \$\endgroup\$ – Brad Gilbert b2gills Dec 16 '17 at 17:33

11 Answers 11

14
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ @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. \$\endgroup\$ – Arnauld Dec 16 '17 at 15:43
  • \$\begingroup\$ -1 byte \$\endgroup\$ – Herman L Dec 16 '17 at 16:35
  • \$\begingroup\$ @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.) \$\endgroup\$ – Arnauld Dec 16 '17 at 16:44
  • \$\begingroup\$ And if you post your answer too soon, it will make people to mostly use your approach... \$\endgroup\$ – user202729 Dec 17 '17 at 3:14
12
\$\begingroup\$

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..*))

\$\endgroup\$
  • 3
    \$\begingroup\$ Wait, Perl 6 has a built-in for this exact thing? \$\endgroup\$ – Erik the Outgolfer Dec 16 '17 at 20:14
  • 2
    \$\begingroup\$ @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. \$\endgroup\$ – tchrist Dec 17 '17 at 4:41
7
\$\begingroup\$

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.

\$\endgroup\$
  • 1
    \$\begingroup\$ -2 bytes on both versions with -~'3 1'[n-6] \$\endgroup\$ – Arnauld Dec 16 '17 at 21:07
7
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

Swift, 106 82 bytes

Port of @Arnaulds JavaScript answer

Saved 24 bytes thanks to @Mr.Xcoder

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

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Use closures for 82 bytes (you don’t have to include var f= in the byte count) \$\endgroup\$ – Mr. Xcoder Dec 16 '17 at 17:13
1
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

Python 3, 97 bytes

lambda m,n:'½ ⅓⅔ ¼_¾ ⅕⅖⅗⅘ ⅙___⅚ ⅐ ⅛_⅜_⅝_⅞ ⅑ ⅒'.split()[n-2][m-1]
\$\endgroup\$
  • 2
    \$\begingroup\$ This doesn't seem to work, you need [n-2][m-1] instead. \$\endgroup\$ – Erik the Outgolfer Dec 16 '17 at 17:21
  • \$\begingroup\$ Right, I guess I didn't test it first... \$\endgroup\$ – Ryan McCampbell Dec 17 '17 at 22:18
0
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.