Ad
Parsing
Algorithms
Logic
Strings

// I don't really think there is anything interesting in the original version as the whole "run" thing seems useless if we just use public functions as arguments.

Your task is to write a Calculator class.

The class should have one public static method which receives an expression given in string to evaluate and returns an int.

The given expression will be in the format (operation [argument list]), with the number of arguments no smaller than 2, for example:

"(add 1 9)" // meaning 1 + 9
"(sub 2 6 0 8)" // meaning 2 - 6 - 0 - 8
"(div 9 8 5)" // meaning 9 / 8 / 5
"(mul 1 7)" // meaning 1 * 7

Note that an argument can be another expression, for example:

"(add 1 (sub 120 - 26))" // meaning 1 + (120 - 26)

The usage of the class hence should be:

var res = Calculator.Run("(add 1 (sub 120 - 26))");

The value of res is expectedly 95.

Code
Diff
  • using System.Collections.Generic;
    using System;
    
    class Calculator
    {
        public static int Run(string exp)
        {
            // very simple implementation using recursion
            // assuming all the inputs are valid
            int lastDelim = exp.IndexOf(' ');
            Func<int, int, int> op = exp[1..lastDelim] switch
            {
                "add" => ((res, num) => res + num),
                "sub" => ((res, num) => res - num),
                "div" => ((res, num) => res / num),
                "mul" => ((res, num) => res * num),
                _ => ((res, num) => 0)
            };
            var args = new List<int>();
            void consumeArg(string arg)
            {
                if (arg[0] == '(')
                {
                    args.Add(Run(arg));
                }
                else
                {
                    args.Add(int.Parse(arg));
                }
            }
            int nest = 0;
            for (int i = lastDelim + 1; i < exp.Length - 1; ++i)
            {
                switch (exp[i])
                {
                    case '(':
                        ++nest;
                        break;
                    case ')':
                        --nest;
                        break;
                    case ' ':
                        if (nest == 0)
                        {
                            consumeArg(exp[(lastDelim + 1)..i]);
                            lastDelim = i;
                        }
                        break;
                }
            }
            consumeArg(exp[(lastDelim + 1)..^1]);
            int res = args[0];
            for (int i = 1; i < args.Count; ++i)
            {
                res = op(res, args[i]);
            }
            return res;
        }
    }
    • add = lambda *args:sum(args)
    • def minum(*args):
    • xxx = args[0]
    • for i in range(1,len(args)):
    • xxx = xxx - args[i]
    • return xxx
    • def multiply(*args):
    • xxx = 1
    • for i in args:
    • xxx = xxx * i
    • return xxx
    • def divide(*args):
    • xxx = args[0]
    • for i in args[1:]:
    • xxx = xxx / i
    • return xxx
    • def run(func,*args):
    • return func(*args)
    • using System.Collections.Generic;
    • using System;
    • class Calculator
    • {
    • public static int Run(string exp)
    • {
    • // very simple implementation using recursion
    • // assuming all the inputs are valid
    • int lastDelim = exp.IndexOf(' ');
    • Func<int, int, int> op = exp[1..lastDelim] switch
    • {
    • "add" => ((res, num) => res + num),
    • "sub" => ((res, num) => res - num),
    • "div" => ((res, num) => res / num),
    • "mul" => ((res, num) => res * num),
    • _ => ((res, num) => 0)
    • };
    • var args = new List<int>();
    • void consumeArg(string arg)
    • {
    • if (arg[0] == '(')
    • {
    • args.Add(Run(arg));
    • }
    • else
    • {
    • args.Add(int.Parse(arg));
    • }
    • }
    • int nest = 0;
    • for (int i = lastDelim + 1; i < exp.Length - 1; ++i)
    • {
    • switch (exp[i])
    • {
    • case '(':
    • ++nest;
    • break;
    • case ')':
    • --nest;
    • break;
    • case ' ':
    • if (nest == 0)
    • {
    • consumeArg(exp[(lastDelim + 1)..i]);
    • lastDelim = i;
    • }
    • break;
    • }
    • }
    • consumeArg(exp[(lastDelim + 1)..^1]);
    • int res = args[0];
    • for (int i = 1; i < args.Count; ++i)
    • {
    • res = op(res, args[i]);
    • }
    • return res;
    • }
    • }