BEGIN { token[0] = 0 ind = 0 print calc("9-3÷1/3+1") print calc("1/2÷3/4÷5/6×7/8×10") print calc("(1+5×(3+2)-2)÷4") print calc("-1/12-2/12") } function gcd(m, n) { return (n ? gcd(n, m % n) : m) } function lcm(m, n) { return (m * n / gcd(m, n)) } function setfrac(n, d, fac, newn, newd) { if (n == 0){ return 0 } if (d == 0){ return setfrac(n, 1) } fac = gcd(n, d) newn = n / fac newd = d / fac if (newd < 0){ newn *= -1 newd *= -1 } return ((newd == 1) ? newn : (newn "/" newd)) } function reciprocalfrac(f, v) { split(f, v, "/") if (v[2] == 0){ v[2] = 1 } return setfrac(v[2], v[1]) } function multifrac(mf, nf, m, n) { split(mf, m, "/") if (m[2] == 0){ m[2] = 1 } split(nf, n, "/") if (n[2] == 0){ n[2] = 1 } return setfrac(m[1] * n[1], m[2] * n[2]) } function divfrac(mf, nf) { if (nf == 0){ print "error: division by 0" exit 1 } return multifrac(mf, reciprocalfrac(nf)) } function addfrac(mf, nf, fac, m, n, newm, newn) { split(mf, m, "/") if (m[2] == 0){ m[2] = 1 } split(nf, n, "/") if (n[2] == 0){ n[2] = 1 } fac = lcm(m[2], n[2]) newm = m[1] * fac / m[2] newn = n[1] * fac / n[2] return setfrac(newm + newn, fac) } function subfrac(mf, nf) { return addfrac(mf, multifrac(nf, -1)) } function accept(x) { if (x == token[ind]){ ind++ return 1 } return 0 } function digit() { if (accept("0")){ return 0 } if (accept("1")){ return 1 } if (accept("2")){ return 2 } if (accept("3")){ return 3 } if (accept("4")){ return 4 } if (accept("5")){ return 5 } if (accept("6")){ return 6 } if (accept("7")){ return 7 } if (accept("8")){ return 8 } if (accept("9")){ return 9 } return (-1) } function digits( sign, n, v) { sign = 1 if (accept("-")){ sign = -1 } n = digit() if (n < 0){ print "error: expected digit" exit 1 } while(1){ v = digit() if (v < 0) break n = n * 10 + v } return setfrac(sign * n) } function factor( n) { if (accept("(")){ n = expression() if (!accept(")")){ print "error: unmatched brackets" exit 1 } return n } return digits() } function term( n) { n = factor() while(1){ if (accept("*")){ n = multifrac(n, factor()) continue } if (accept("/")){ n = divfrac(n, factor()) continue } break } return n } function multi_exp( n) { n = term() while(1){ if (accept("×")){ n = multifrac(n, term()) continue } if (accept("÷")){ n = divfrac(n, term()) continue } break } return n } function expression( n) { n = multi_exp() while(1){ if (accept("+")){ n = addfrac(n, multi_exp()) continue } if (accept("-")){ n = subfrac(n, multi_exp()) continue } break } return n } function trdigit(v) { if (v == "0"){ return "0" } if (v == "1"){ return "1" } if (v == "2"){ return "2" } if (v == "3"){ return "3" } if (v == "4"){ return "4" } if (v == "5"){ return "5" } if (v == "6"){ return "6" } if (v == "7"){ return "7" } if (v == "8"){ return "8" } if (v == "9"){ return "9" } if (v == "-"){ return "-" } if (v == "/"){ return "/" } } function fractostring(s, i, n, v, r) { n = split(s, v, "") r = "" for(i = 1; i <= n; i++){ r = r trdigit(v[i]) } return r } function calc(s, i, n) { n = split(s, token, "") token[n + 1] = "$" ind = 1 return fractostring(expression()) }