Objective
Given a string with single Unicode vulgar fraction, parse it to a rational number.
Valid inputs
A valid input is one of:
¼
U+00BC; one quarter½
U+00BD; one half¾
U+00BE; three quarters⅐
U+2150; one seventh⅑
U+2151; one ninth⅒
U+2152; one tenth⅓
U+2153; one third⅔
U+2154; two thirds⅕
U+2155; one fifth⅖
U+2156; two fifths⅗
U+2157; three fifths⅘
U+2158; four fifths⅙
U+2159; one sixth⅚
U+215A; five sixths⅛
U+215B; one eighth⅜
U+215C; three eighths⅝
U+215D; five eighths⅞
U+215E; seven eighths⅟
(U+215F; fraction numerator one) followed by ASCII decimal digits (U+0030 – U+0039)ASCII decimal digits followed by
⁄
(U+2044; fraction slash) followed by ASCII decimal digits
There are exceptions. See below.
Invalid inputs
If the denominator is zero, the parser must fall in an erroneous state. This includes:
Monadic failing
Returning an erroneous value
Throwing an error
Rules
Encoding of the input doesn't matter.
Output type and format doesn't matter either. Though native rational number type is preferred, a pair of integers is permitted.
Inputs that are neither valid nor invalid fall in don't care situation. This includes:
Whole numbers
Improper fractions
Reducible fractions
Fractions with zero numerator
Negative fractions
Examples
⅛
(U+215B) parses to one eighth.
⅟13
(U+215F U+0031 U+0033) parses to one thirteenth.
24⁄247
(U+0032 U+0034 U+2044 U+0032 U+0034 U+0037) parses to twenty-four 247ths.
1⁄7
(U+0031 U+2044 U+0037) parses to one seventh. Note that ⅐
and ⅟7
will parse to the same.
0
(U+0030) falls in don't care situation. It's a whole number.
9⁄8
(U+0039 U+2044 U+0038) falls in don't care situation. It's an improper fraction.
4⁄8
(U+0034 U+2044 U+0038) falls in don't care situation. It's reducible to one half.
↉
(U+2189) falls in don't care situation. Its numerator is zero.
-½
(U+002D U+00BD) falls in don't care situation. It is negative.
1⁄0
(U+0031 U+2044 U+0030) must make the parser be in erroneous state. Its denominator is zero.
Ungolfed solution
Haskell
import Control.Monad
import Data.Ratio
import Text.ParserCombinators.ReadP as ReadP
import Text.Read
import Text.Read.Lex
fractionParser :: ReadP Rational
fractionParser = choice [
char '¼' >> return (1 % 4),
char '½' >> return (1 % 2),
char '¾' >> return (3 % 4),
char '⅐' >> return (1 % 7),
char '⅑' >> return (1 % 9),
char '⅒' >> return (1 % 10),
char '⅓' >> return (1 % 3),
char '⅔' >> return (2 % 3),
char '⅕' >> return (1 % 5),
char '⅖' >> return (2 % 5),
char '⅗' >> return (3 % 5),
char '⅘' >> return (4 % 5),
char '⅙' >> return (1 % 6),
char '⅚' >> return (5 % 6),
char '⅛' >> return (1 % 8),
char '⅜' >> return (3 % 8),
char '⅝' >> return (5 % 8),
char '⅞' >> return (7 % 8),
char '⅟' >> do
d <- readDecP
guard (0 /= d)
return (1 % d),
do
n <- readDecP
char '⁄'
d <- readDecP
guard (0 /= d)
return (n % d)
]
ToExpression
, that converts a string to a number or other mathematical expression ... that utterly fails to understand these symbols :) \$\endgroup\$