fork download
  1. BEGIN {
  2. token[0] = 0
  3. ind = 0
  4.  
  5. print calc("9-3÷1/3+1")
  6. print calc("1/2÷3/4÷5/6×7/8×10")
  7. print calc("(1+5×(3+2)-2)÷4")
  8. print calc("-1/12-2/12")
  9. }
  10.  
  11. function gcd(m, n) {
  12. return (n ? gcd(n, m % n) : m)
  13. }
  14.  
  15. function lcm(m, n) {
  16. return (m * n / gcd(m, n))
  17. }
  18.  
  19. function setfrac(n, d, fac, newn, newd) {
  20. if (n == 0){
  21. return 0
  22. }
  23. if (d == 0){
  24. return setfrac(n, 1)
  25. }
  26.  
  27. fac = gcd(n, d)
  28. newn = n / fac
  29. newd = d / fac
  30. if (newd < 0){
  31. newn *= -1
  32. newd *= -1
  33. }
  34.  
  35. return ((newd == 1) ? newn : (newn "/" newd))
  36. }
  37.  
  38. function reciprocalfrac(f, v) {
  39. split(f, v, "/")
  40. if (v[2] == 0){
  41. v[2] = 1
  42. }
  43.  
  44. return setfrac(v[2], v[1])
  45. }
  46.  
  47. function multifrac(mf, nf, m, n) {
  48. split(mf, m, "/")
  49. if (m[2] == 0){
  50. m[2] = 1
  51. }
  52. split(nf, n, "/")
  53. if (n[2] == 0){
  54. n[2] = 1
  55. }
  56.  
  57. return setfrac(m[1] * n[1], m[2] * n[2])
  58. }
  59.  
  60. function divfrac(mf, nf) {
  61. if (nf == 0){
  62. print "error: division by 0"
  63. exit 1
  64. }
  65.  
  66. return multifrac(mf, reciprocalfrac(nf))
  67. }
  68.  
  69. function addfrac(mf, nf, fac, m, n, newm, newn) {
  70. split(mf, m, "/")
  71. if (m[2] == 0){
  72. m[2] = 1
  73. }
  74. split(nf, n, "/")
  75. if (n[2] == 0){
  76. n[2] = 1
  77. }
  78.  
  79. fac = lcm(m[2], n[2])
  80. newm = m[1] * fac / m[2]
  81. newn = n[1] * fac / n[2]
  82.  
  83. return setfrac(newm + newn, fac)
  84. }
  85.  
  86. function subfrac(mf, nf) {
  87. return addfrac(mf, multifrac(nf, -1))
  88. }
  89.  
  90.  
  91. function accept(x) {
  92. if (x == token[ind]){
  93. ind++
  94. return 1
  95. }
  96.  
  97. return 0
  98. }
  99.  
  100. function digit() {
  101. if (accept("0")){
  102. return 0
  103. }
  104. if (accept("1")){
  105. return 1
  106. }
  107. if (accept("2")){
  108. return 2
  109. }
  110. if (accept("3")){
  111. return 3
  112. }
  113. if (accept("4")){
  114. return 4
  115. }
  116. if (accept("5")){
  117. return 5
  118. }
  119. if (accept("6")){
  120. return 6
  121. }
  122. if (accept("7")){
  123. return 7
  124. }
  125. if (accept("8")){
  126. return 8
  127. }
  128. if (accept("9")){
  129. return 9
  130. }
  131.  
  132. return (-1)
  133. }
  134.  
  135. function digits( sign, n, v) {
  136. sign = 1
  137. if (accept("-")){
  138. sign = -1
  139. }
  140.  
  141. n = digit()
  142. if (n < 0){
  143. print "error: expected digit"
  144. exit 1
  145. }
  146.  
  147. while(1){
  148. v = digit()
  149. if (v < 0) break
  150. n = n * 10 + v
  151. }
  152.  
  153. return setfrac(sign * n)
  154. }
  155.  
  156. function factor( n) {
  157. if (accept("(")){
  158. n = expression()
  159. if (!accept(")")){
  160. print "error: unmatched brackets"
  161. exit 1
  162. }
  163. return n
  164. }
  165.  
  166. return digits()
  167. }
  168.  
  169. function term( n) {
  170. n = factor()
  171. while(1){
  172. if (accept("*")){
  173. n = multifrac(n, factor())
  174. continue
  175. }
  176. if (accept("/")){
  177. n = divfrac(n, factor())
  178. continue
  179. }
  180. break
  181. }
  182.  
  183. return n
  184. }
  185.  
  186. function multi_exp( n) {
  187. n = term()
  188. while(1){
  189. if (accept("×")){
  190. n = multifrac(n, term())
  191. continue
  192. }
  193. if (accept("÷")){
  194. n = divfrac(n, term())
  195. continue
  196. }
  197. break
  198. }
  199.  
  200. return n
  201. }
  202.  
  203. function expression( n) {
  204. n = multi_exp()
  205. while(1){
  206. if (accept("+")){
  207. n = addfrac(n, multi_exp())
  208. continue
  209. }
  210. if (accept("-")){
  211. n = subfrac(n, multi_exp())
  212. continue
  213. }
  214. break
  215. }
  216.  
  217. return n
  218. }
  219.  
  220. function trdigit(v) {
  221. if (v == "0"){
  222. return "0"
  223. }
  224. if (v == "1"){
  225. return "1"
  226. }
  227. if (v == "2"){
  228. return "2"
  229. }
  230. if (v == "3"){
  231. return "3"
  232. }
  233. if (v == "4"){
  234. return "4"
  235. }
  236. if (v == "5"){
  237. return "5"
  238. }
  239. if (v == "6"){
  240. return "6"
  241. }
  242. if (v == "7"){
  243. return "7"
  244. }
  245. if (v == "8"){
  246. return "8"
  247. }
  248. if (v == "9"){
  249. return "9"
  250. }
  251. if (v == "-"){
  252. return "-"
  253. }
  254. if (v == "/"){
  255. return "/"
  256. }
  257. }
  258.  
  259. function fractostring(s, i, n, v, r) {
  260. n = split(s, v, "")
  261.  
  262. r = ""
  263. for(i = 1; i <= n; i++){
  264. r = r trdigit(v[i])
  265. }
  266.  
  267. return r
  268. }
  269.  
  270. function calc(s, i, n) {
  271. n = split(s, token, "")
  272. token[n + 1] = "$"
  273. ind = 1
  274.  
  275. return fractostring(expression())
  276. }
  277.  
Success #stdin #stdout 0.04s 4280KB
stdin
Standard input is empty
stdout
1
7
6
-1/4