Guest User

Untitled

a guest
Apr 27th, 2021
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.18 KB | None | 0 0
  1. public class Solution {
  2.     public IList<string> BasicCalculatorIV(string expression, string[] evalvars, int[] evalints) {
  3.         var vars = new Dictionary<string, int>();
  4.        
  5.         for (int i = 0; i < evalvars.Length; i++) {
  6.             vars[evalvars[i]] = evalints[i];
  7.         }
  8.        
  9.         var result = Calculate(expression, vars);
  10.        
  11.         return ((NodeValuePoly)result).GetList();
  12.     }
  13.  
  14.     char[][] operationsOrder = new char[][]{
  15.         new char[]{'*', '/'},
  16.         new char[]{'+','-'}
  17.     };
  18.  
  19.     private NodeValuePoly Calculate(string s, Dictionary<string, int> vars) {
  20.         int charIndex = 0;
  21.  
  22.         var root = BuildLinkedList(s, ref charIndex);
  23.  
  24.         return CalculateList(root, vars);
  25.     }
  26.  
  27.     private NodeValuePoly CalculateList(Node root, Dictionary<string, int> vars) {
  28.         PrintList(root);
  29.         var node = root;
  30.        
  31.         while (node != null) {
  32.             ResolveNode(node, vars);
  33.             node = node.next;
  34.         }
  35.        
  36.         foreach (var operations in operationsOrder) {
  37.             PrintList(root);
  38.             node = root;
  39.  
  40.             while (node.next != null) {
  41.                 if (operations.Contains(node.operation)) {
  42.                     ExecuteNode(node);
  43.                 } else {
  44.                     node = node.next;
  45.                 }    
  46.             }
  47.         }
  48.  
  49.         if (root.next != null) {
  50.             throw new Exception("List must have only 1 value at this point!");
  51.         }
  52.         PrintList(root);
  53.  
  54.         return (NodeValuePoly)root.GetValue();
  55.     }
  56.  
  57.     private void PrintList(Node node) {
  58.         while (node != null) {
  59.             Console.Write(" {0}{1} {2}", node.isNegative ? "{-}": "", node.GetValue(), node.operation);
  60.             node = node.next;
  61.         }
  62.         Console.WriteLine();
  63.     }
  64.    
  65.     void ExecuteNode(Node node) {
  66.         var a = EvaluateNodeValue(node);;
  67.         var b = EvaluateNodeValue(node.next);
  68.        
  69.         NodeValuePoly c;
  70.        
  71.         switch (node.operation) {
  72.             case '+':
  73.                 c = PolyAdd(a, b, 1);
  74.                 break;
  75.             case '-':
  76.                 c = PolyAdd(a, b, -1);
  77.                 break;
  78.             case '*':
  79.                 c = PolyMult(a, b, 1);
  80.                 // c = a * b;
  81.                 break;
  82.             case '/':
  83.                 throw new Exception("/");
  84.                 // c = a / b;
  85.                 break;
  86.             default:
  87.                 throw new Exception("illegal operator");
  88.         }
  89.  
  90.         node.SetValue(c);
  91.         node.isNegative = false;
  92.         node.operation = node.next.operation;
  93.         node.next = node.next.next;
  94.     }
  95.    
  96.     private NodeValuePoly PolyAdd(NodeValuePoly a, NodeValuePoly b, int bMultiplier) {
  97.         NodeValuePoly c = new NodeValuePoly();
  98.        
  99.         foreach (var pair in a.polies) {
  100.             SetDic(c.polies, pair.Key, pair.Value);
  101.         }
  102.        
  103.         foreach (var pair in b.polies) {
  104.             SetDic(c.polies, pair.Key, GetDic(c.polies, pair.Key) + pair.Value * bMultiplier);
  105.         }
  106.        
  107.         return c;
  108.     }
  109.    
  110.     private NodeValuePoly PolyMult(NodeValuePoly a, NodeValuePoly b, int bMultiplier) {
  111.         NodeValuePoly c = new NodeValuePoly();
  112.        
  113.         foreach (var pairA in a.polies) {
  114.             foreach (var pairB in b.polies) {
  115.                 PolyKey key = new PolyKey();
  116.                
  117.                 foreach (var vari in pairA.Key.variables) {
  118.                     SetDic(key.variables, vari.Key, vari.Value);
  119.                 }
  120.  
  121.                 foreach (var vari in pairB.Key.variables) {
  122.                     SetDic(key.variables, vari.Key, GetDic(key.variables, vari.Key) + vari.Value * bMultiplier);
  123.                 }
  124.                
  125.                 int coef = pairA.Value;
  126.                 if (bMultiplier == 1) {
  127.                     coef *= pairB.Value;
  128.                 } else {
  129.                     coef /= pairB.Value;
  130.                 }
  131.                
  132.                 SetDic(c.polies, key, GetDic(c.polies, key) + coef);
  133.             }
  134.         }
  135.        
  136.         return c;
  137.     }
  138.    
  139.     private NodeValuePoly EvaluateNodeValue(Node node) {
  140.         return ((NodeValuePoly)node.GetValue());
  141.     }
  142.    
  143.     private void ResolveNode(Node node, Dictionary<string, int> vars) {
  144.         var value = node.GetValue();
  145.  
  146.         // Fixing constants
  147.         if (value is NodeValueVariable) {
  148.             var variable = ((NodeValueVariable)value).variable;
  149.            
  150.             int valint;
  151.            
  152.             if (int.TryParse(variable, out valint)) {
  153.                 value = new NodeValueInt() {val = valint};
  154.             } else if (vars.ContainsKey(variable)) {
  155.                 value = new NodeValueInt() {val = vars[variable]};
  156.             }
  157.         }
  158.        
  159.         if (value is NodeValueExpression) {
  160.             value = CalculateList(((NodeValueExpression)value).node, vars);
  161.         } else if (value is NodeValueInt) {
  162.             value = new NodeValuePoly((value as NodeValueInt).val);
  163.         } else if (value is NodeValueVariable) {
  164.             value = new NodeValuePoly((value as NodeValueVariable).variable);
  165.         } else {
  166.             throw new Exception("Unsupported expression type");
  167.         }
  168.        
  169.         /*var valueInt = (NodeValueInt)value;
  170.        
  171.         if (node.isNegative) {
  172.             valueInt.val = -valueInt.val;
  173.         }
  174.         node.SetValue(valueInt);
  175.         node.isNegative = false;*/
  176.        
  177.         if  (node.isNegative) {
  178.             throw new Exception("Negative node is not supported");
  179.         }
  180.        
  181.         node.SetValue(value);
  182.     }
  183.    
  184.     char[] operations = new char[]{ '+', '-', '*', '/' };
  185.    
  186.     private Node BuildLinkedList(string s, ref int charIndex) {
  187.         var root = new Node();
  188.         var node = root;
  189.        
  190.         bool expectSign = true;
  191.         //bool isNegative = false;
  192.        
  193.         while (charIndex < s.Length) {
  194.             var c = s[charIndex];
  195.             charIndex++;
  196.            
  197.             if (c == ' ') {
  198.                 // noop
  199.             } else if (char.IsDigit(c) || char.IsLetter(c)) {
  200.                 if (node.GetValue() == null) {
  201.                     node.SetValue(new NodeValueVariable() { variable = "" });
  202.                 }
  203.                
  204.                 var nodeValue = node.GetValue() as NodeValueVariable;
  205.                
  206.                 expectSign = false;
  207.                 var digit = c - '0';
  208.                 nodeValue.variable = nodeValue.variable + c;
  209.                 //if (isNegative) {
  210.                 //    nodeValue.val = -nodeValue.val;
  211.                 //}
  212.             } else if (operations.Contains(c)) {
  213.                 if (expectSign && c == '-') {
  214.                     node.isNegative = true;
  215.                 } else {
  216.                     node.operation = c;
  217.                     node.next = new Node();
  218.                     node = node.next;
  219.                    
  220.                     expectSign = true;
  221.                     //isNegative = false;
  222.                 }
  223.             } else if (c == '(') {
  224.                 expectSign = false;
  225.                 var nodeValue = new NodeValueExpression();
  226.                 nodeValue.node = BuildLinkedList(s, ref charIndex);
  227.                 //nodeValue.val = Calculate(s, ref charIndex);
  228.  
  229.                 //if (isNegative) {
  230.                 //    nodeValue.val = -nodeValue.val;
  231.                 //}
  232.                 node.SetValue(nodeValue);
  233.             } else if (c == ')') {
  234.                 break;
  235.             }
  236.         }
  237.        
  238.         return root;
  239.     }
  240.    
  241.     class Node {
  242.         public char operation;
  243.         public Node next;
  244.  
  245.         private NodeValue value;
  246.        
  247.         public bool isNegative;
  248.        
  249.         public NodeValue GetValue() {
  250.             return this.value;
  251.         }
  252.        
  253.         public void SetValue(NodeValue value) {
  254.             this.value = value;
  255.         }
  256.     }
  257.    
  258.     abstract class NodeValue {
  259.        
  260.     }
  261.    
  262.     class NodeValueInt : NodeValue {
  263.         public int val;
  264.        
  265.         public override string ToString() {
  266.             return val.ToString();
  267.         }
  268.     }
  269.    
  270.     class NodeValueExpression : NodeValue {
  271.         public Node node;
  272.     }
  273.    
  274.     class NodeValueVariable : NodeValue {
  275.         public string variable;
  276.  
  277.         public override string ToString() {
  278.             return variable;
  279.         }
  280.     }
  281.    
  282.     class NodeValuePoly : NodeValue {
  283.         public Dictionary<PolyKey, int> polies = new Dictionary<PolyKey, int>();
  284.        
  285.         public NodeValuePoly() {
  286.            
  287.         }
  288.        
  289.         public NodeValuePoly(int constant) {
  290.             PolyKey key = new PolyKey();
  291.             SetDic(polies, key, constant);
  292.         }
  293.        
  294.         public NodeValuePoly(string variable) {
  295.             PolyKey key = new PolyKey();
  296.             SetDic(key.variables, variable, 1);
  297.             SetDic(polies, key, 1);
  298.             Console.WriteLine("XXX " + this.ToString() + " " + this.polies.Count);
  299.         }
  300.        
  301.         public List<String> GetList() {
  302.             List<string> result = new List<string>();
  303.            
  304.             foreach (var component in polies.OrderByDescending(p=> p.Key.Power).ThenBy(p=> p.Key.ToString())) {
  305.                 result.Add(component.Value.ToString() + component.Key.ToString());
  306.             }
  307.            
  308.             return result;
  309.         }
  310.        
  311.         public override String ToString() {
  312.             return String.Join(" | ", GetList());
  313.         }
  314.     }
  315.    
  316.     class PolyKey {
  317.         public Dictionary<string, int> variables = new Dictionary<string, int>();
  318.        
  319.         public override bool Equals (object obj) {
  320.             PolyKey other = (PolyKey)obj;
  321.            
  322.             return this.variables.Count == other.variables.Count && !this.variables.Except(other.variables).Any();
  323.         }
  324.        
  325.         public override int GetHashCode() {
  326.             HashCode hashCode = new HashCode();
  327.            
  328.             foreach (var pair in variables.OrderBy(p=> p.Key)) {
  329.                 hashCode.Add(pair.Key);
  330.                 hashCode.Add(pair.Value);
  331.             }
  332.            
  333.             return hashCode.ToHashCode();
  334.         }
  335.        
  336.         public int Power {
  337.             get{
  338.                 return variables.Select(p=> p.Value).Sum();
  339.             }
  340.         }
  341.        
  342.         public override string ToString() {
  343.             StringBuilder sb = new StringBuilder();
  344.            
  345.             foreach (var pair in variables.OrderBy(v=> v.Key)) {
  346.                 for (int i = 0; i < pair.Value; i++) {
  347.                     sb.Append("*");
  348.                     sb.Append(pair.Key);
  349.                 }
  350.             }
  351.            
  352.             return sb.ToString();
  353.         }
  354.     }
  355.    
  356.     private static void SetDic<TKey>(Dictionary<TKey, int> dic, TKey key, int value) {
  357.         dic[key] = value;
  358.        
  359.         if (dic[key] == 0) {
  360.             dic.Remove(key);
  361.         }
  362.     }
  363.    
  364.     private static int GetDic<TKey>(Dictionary<TKey, int> dic, TKey key) {
  365.         if (dic.ContainsKey(key)) {
  366.             return dic[key];
  367.         } else {
  368.             return 0;
  369.         }
  370.     }
  371. }
  372.  
Add Comment
Please, Sign In to add comment