Ejemplo n.º 1
0
 private static bool _prepare(MultiLinker <KeyValuePair <char, string> > s, Func <MultiLinker <KeyValuePair <char, string> > > func)
 {
     if (s == null || s.Link == null)
     {
         return(false);
     }
     //NormSignDown(s, '+', '-'); NormSignDown(s, '*', '/');
     foreach (var pair in s)
     {
         var p = pair.Data;
         if (p.Link == null)
         {
             continue;
         }
         NormSignDown(p, '+', '-'); NormSignDown(p, '*', '/');
         if (NormGetUp(s, pair))
         {
             continue;
         }
         pair.Data = (func ?? (m => { _prepare(m, null); return(m); }))(p);
         NormGetUp(s, pair);
     }
     NormMinusUp(s, m => m.Link.Data.Data.Key == '-'
                 //{ foreach(var pair in m) if(pair.Data.Data.Key == '+') return false; return true; }
                 );
     return(true);
 }
Ejemplo n.º 2
0
        private static bool NormGetUp(MultiLinker <KeyValuePair <char, string> > s, MonoLinker <MultiLinker <KeyValuePair <char, string> > > mono)
        {
            if (mono.Data.Link == null || mono.Data.Link.Data == null)
            {
                return(false);
            }
            if (!_check20(mono.Data.Data.Key, mono.Data.Link.Data.Data.Key))
            {
                return(false);
            }
            //var p = pair.Data; KeyValuePair<char, string> v1 = p.Data, v2 = p.Link.Data.Data;
            //if((v1.Key != '+' || (v2.Key != '+' && v2.Key != '-')) && (v1.Key != '*' || (v2.Key != '*' && v2.Key != '/'))) return false;
            var copy = mono.Data.Link.GetCopy();

            copy.GetLast().Link = mono.Link;
            //pair.Link = copy; s.Remove(pair);
            if (s.Link == mono)
            {
                s.Link = copy;
            }
            else
            {
                s.Link.GetBefore(mono).Link = copy;
            }
            return(true);
        }
Ejemplo n.º 3
0
        private static KeyValuePair <char, string> ToSignedString(MultiLinker <KeyValuePair <char, string> > s)
        {
            if (s == null)
            {
                return(default(KeyValuePair <char, string>));
            }
            if (s.Link == null)
            {
                return(s.Data);
            }
            var  sb = new StringBuilder();
            bool t  = true,
                 b  = (s.Data.Key == '*' || s.Data.Key == '/') && s.Link.Data.Data.Key == '-' ||
                      s.Link.Link != null && (s.Data.Key == '/' ||
                                              ((s.Data.Key == '-' || s.Data.Key == '*') &&
                                               (s.Link.Data.Data.Key == '+' || s.Link.Data.Data.Key == '-')));

            if (b)
            {
                sb.Append(@"(");
            }
            foreach (var pair in s)
            {
                var c = ToSignedString(pair.Data);
                if ((EqualsPorN(c.Key, '+', '-') && c.Value == Zero) ||
                    (EqualsPorN(c.Key, '*', '/') && c.Value == One))
                {
                    continue;
                }
                if (EqualsPorN(c.Key, '*', '/') && c.Value == Zero)
                {
                    return(new KeyValuePair <char, string>('+', Zero));
                }
                if (t && c.Key == '/')
                {
                    sb.Append(One);
                }
                if (!t || (c.Key != '+' && c.Key != '*'))
                {
                    sb.Append(c.Key);
                }
                sb.Append(c.Value);
                t = false;
            }
            if (t)
            {
                sb.Append(EqualsPorN(s.Link.Data.Data.Key, '*', '/') ? One : Zero);
            }
            if (b)
            {
                sb.Append(@")");
            }
            return(new KeyValuePair <char, string>(s.Data.Key, sb.ToString()));
        }
Ejemplo n.º 4
0
        /// <summary><returns> Common factor </returns></summary>
        public static string CommonMultiplier(params string[] ss)
        {
            int len = ss.GetLength(0), i = -1;
            var gg = new MultiLinker <KeyValuePair <char, string> > [len];

            while (++i < len)
            {
                gg[i] = ArithmeticGraph(ss[i]);
            }
            return(ToString(CommonMultiplier((IEnumerable <MultiLinker <KeyValuePair <char, string> > >)gg)));
        }
Ejemplo n.º 5
0
        /// <summary> Відкриває всі дужки і повертає<returns> суму добутків </returns></summary>
        public static MultiLinker <KeyValuePair <char, string> > FullExpand(MultiLinker <KeyValuePair <char, string> > s)
        {
            if (!_prepare(s, FullExpand))
            {
                return(s);
            }
            if ((s.Data.Key != '+' && s.Data.Key != '-') || (s.Link.Data.Data.Key != '*' && s.Link.Data.Data.Key != '/'))
            {
                return(s);
            }
            var clone = s.Clone();

            clone.Link = null;
            clone.Add(new KeyValuePair <char, string>('+', One));
            foreach (var pair in s)
            {
                if (pair.Data.Link == null || pair.Data.Data.Key == '/')
                {
                    foreach (var c in clone)
                    {
                        if (pair.Data.Data.Value != One)
                        {
                            c.Data.Add(pair.Data);
                        }
                    }
                }
                else
                {
                    var temp = s.Clone();
                    temp.Link = null;
                    foreach (var c in clone)
                    {
                        foreach (var p in pair.Data)
                        {
                            var copy = c.Data.GetCopy();
                            if (p.Data.Link != null)
                            {
                                copy.Add(p.Data.Link);
                            }
                            else if (p.Data.Data.Value != One)
                            {
                                copy.Add(s.Clone(new KeyValuePair <char, string>(
                                                     pair.Data.Data.Key, p.Data.Data.Value), p.Data.Link));
                            }
                            temp.Add(p.Data.Data.Key == '-' ? ChangeSign(copy, '+', '-') : copy);
                        }
                    }
                    clone = temp;
                }
            }
            NormSignDown(clone, '+', '-');
            return(clone.Link.Link == null ? clone.Link.Data : clone);
        }
Ejemplo n.º 6
0
 public static bool NormSignDown(MultiLinker <KeyValuePair <char, string> > s, char pstv, char ngtv)
 {
     if (s == null || s.Link == null || !_check21(s.Data.Key, s.Link.Data.Data.Key, ngtv, pstv))
     {
         return(false);
     }
     s.Data = new KeyValuePair <char, string>(pstv, s.Data.Value);
     foreach (var pair in (IEnumerable <MultiLinker <KeyValuePair <char, string> > >)s)
     {
         ChangeSign(pair, pstv, ngtv);
     }
     return(true);
 }
Ejemplo n.º 7
0
        //private static string StrAdd(string s1, string s2) { return s1 == Zero ? s2 : s2 == Zero ? s1 : string.Concat(s1, @"+", s2); }
        //private static string StrMult(string s1, string s2) { return s1 == One ? s2 : s2 == One ? s1 : string.Concat(s1, @"*", s2); }
        public static MultiLinker <KeyValuePair <char, string> > ArithmeticGraph(string s, char ch = '+')
        {
            var g = new MultiLinker <KeyValuePair <char, string> >(new KeyValuePair <char, string>(ch, s = TrimBrackets(s)));
            MonoLinker <KeyValuePair <char, string> > split;

            if ((split = SplitSum(s, true)).Link == null && s == split.Data.Value &&
                (split = SplitProduct(s, true)).Link == null && s == split.Data.Value)
            {
                return(g);
            }
            foreach (var pair in split)
            {
                g.Link = new MonoLinker <MultiLinker <KeyValuePair <char, string> > >(
                    ArithmeticGraph(pair.Data.Value, pair.Data.Key), g.Link);
            }
            return(g);
        }
Ejemplo n.º 8
0
 /// <summary> Розкриває всі дужки, в яких операції такі як за дужками </summary>
 public static MultiLinker <KeyValuePair <char, string> > Normalize(MultiLinker <KeyValuePair <char, string> > s)
 {
     if (s == null)
     {
         return(null);
     }
     while (s.Link != null && s.Link.Link == null &&
            (EqualsPorN(s.Link.Data.Data.Key, '+', '*') ||
             _check21(s.Link.Data.Data.Key, s.Data.Key, '-', '+')))
     {
         if (s.Link.Data.Link == null)
         {
             s.Data = new KeyValuePair <char, string>(s.Data.Key, s.Link.Data.Data.Value);
         }
         (s.Link.Data.Data.Key == '-' ? ChangeSign(s, '+', '-') : s).Link = s.Link.Data.Link;
     }
     NormSignDown(s, '+', '-'); NormSignDown(s, '*', '/');
     if (s.Link == null)
     {
         return(s);
     }
     foreach (var pair in s)
     {
         if (pair.Data.Link == null)
         {
             continue;
         }
         pair.Data = Normalize(pair.Data);
         NormGetUp(s, pair);
     }
     NormMinusUp(s, m => { foreach (var pair in m)
                           {
                               if (pair.Data.Data.Key == '+')
                               {
                                   return(false);
                               }
                           }
                           return(true); });                                                                              //*/
     //_prepare(s, null/*Normalize*/);
     return(s);
 }
Ejemplo n.º 9
0
 public static MultiLinker <KeyValuePair <char, string> > Sort(MultiLinker <KeyValuePair <char, string> > s, Comparison <MultiLinker <KeyValuePair <char, string> > > compar = null)
 {
     if (s == null || s.Link == null)
     {
         return(s);
     }
     if (compar == null)
     {
         compar = (m1, m2) => string.CompareOrdinal(m1.Data.Value, m2.Data.Value);
     }
     foreach (var pair in s)
     {
         pair.Data = Sort(pair.Data, compar);
     }
     foreach (var pair in s)
     {
         if (pair.Link == null)
         {
             continue;
         }
         var t = pair;
         foreach (var p in pair.Link)
         {
             if (compar(p.Data, t.Data) < 0)
             {
                 t = p;
             }
         }
         if (t == pair)
         {
             continue;
         }
         var data = pair.Data;
         pair.Data = t.Data;
         t.Data    = data;
     }
     return(s);
 }
Ejemplo n.º 10
0
        public static bool EqualsByValue(MultiLinker <KeyValuePair <char, string> > s1, MultiLinker <KeyValuePair <char, string> > s2, bool ignoreSign = false)
        {
            if (s1 == s2)
            {
                return(true);
            }
            if (s1 == null || s2 == null)
            {
                return(false);
            }
            bool b1 = s1.Link == null, b2 = s2.Link == null;

            if (b1 || b2)
            {
                return((b1 ? s1.Data : ToSignedString(s1)).Value == (b2 ? s2.Data : ToSignedString(s2)).Value);
            }

            /*
             * s1 = FullExpand(s1);
             * s2 = FullExpand(s2);
             * //*/
            return(ToSignedString(s1).Value == ToSignedString(s2).Value);
        }
Ejemplo n.º 11
0
        public static bool NormMinusUp(MultiLinker <KeyValuePair <char, string> > s, Predicate <MultiLinker <KeyValuePair <char, string> > > pred)
        {
            if (s == null || s.Link == null || !EqualsPorN(s.Data.Key, '+', '-') /* || !EqualsPorN(s.Link.Data.Data.Key, '*', '/')*/)
            {
                return(false);
            }
            var b = false;
            Action <MultiLinker <KeyValuePair <char, string> > > act = m => {
                if (m.Link == null || !EqualsPorN(m.Link.Data.Data.Key, '+', '-') || !pred(m))
                {
                    return;
                }
                b ^= true;
                foreach (var p in (IEnumerable <MultiLinker <KeyValuePair <char, string> > >)m)
                {
                    ChangeSign(p, '+', '-');
                }
            };

            if (EqualsPorN(s.Link.Data.Data.Key, '*', '/'))
            {
                foreach (var pair in (IEnumerable <MultiLinker <KeyValuePair <char, string> > >)s)
                {
                    act(pair);
                }
            }
            else
            {
                act(s);
            }
            if (b)
            {
                ChangeSign(s, '+', '-');
            }
            return(true);
        }
Ejemplo n.º 12
0
        public static MultiLinker <KeyValuePair <char, string> > Simplify(MultiLinker <KeyValuePair <char, string> > s, Comparison <MultiLinker <KeyValuePair <char, string> > > compar)
        {
            var    g = s;
            string gS = ToString(s), sS;

            do /*s = g;//*/ sS {
Ejemplo n.º 13
0
 public static MultiLinker <KeyValuePair <char, string> > Simplify(MultiLinker <KeyValuePair <char, string> > s)
 {
     return(Simplify(s, null));
 }
Ejemplo n.º 14
0
 public static MultiLinker <KeyValuePair <char, string> > Factor(MultiLinker <KeyValuePair <char, string> > s)
 {
     return(s);
 }
Ejemplo n.º 15
0
        /// <summary> Annihilate </summary>
        public static MultiLinker <KeyValuePair <char, string> > Cancel(MultiLinker <KeyValuePair <char, string> > s)
        {
            if (!_prepare(s, Cancel))
            {
                return(s);
            }
            bool   mult = EqualsPorN(s.Link.Data.Data.Key, '*', '/');
            double sum = mult ? 1d : 0d, n = 0d;

            foreach (var pair in s)
            {
                var p = pair.Data;
                if (IsNum(p.Data.Value))
                {
                    //try {
                    var num = ToNum(p.Data.Value);
                    if (num.Equals(0d) && mult)
                    {
                        return(s.Clone(new KeyValuePair <char, string>(s.Data.Key,
                                                                       num.ToString(CultureInfo.InvariantCulture)), null));
                    }
                    switch (p.Data.Key)
                    {
                    case '+': sum += num; break;

                    case '-': sum -= num; break;

                    case '*': sum *= num; break;

                    case '/': sum /= num; break;
                    }
                    s.Remove(pair);
                }
                else
                {
                    //catch {
                    var c = (char)(mult ? (p.Data.Key ^ '*' ^ '/') : (p.Data.Key ^ '+' ^ '-'));
                    if (pair.Remove(mono => mono != null && mono.Data != null &&
                                    (mono.Data.Data.Key == c && EqualsByValue(mono.Data, p) /* ||
                                                                                             * mono.Data.Data.Key == p.Data.Key && EqualsByValue(mono.Data, p)*/)))
                    {
                        s.Remove(pair); continue;
                    }

                    /*
                     * if(pair.Data.Link == null)
                     * {
                     *      var temp = s.Link.Find(mono => mono != null && mono.Data != null &&
                     *              mono.Data.Count > 1 &&
                     *              IsNum(mono.Data.Link.Data.Data.Value) &&
                     *              EqualsByValue(mono.Data.Link.Link.Data.Data.Value, p.Value));
                     *      if(false)
                     *              s.Remove(pair);
                     * }
                     * //*/
                    //
                    if (EqualsPorN(p.Data.Key, '+', '-') && (p.Data.Value == @"n" ||
                                                             (p.Link != null && p.Link.Link != null && p.Link.Link.Link == null &&
                                                              IsNum(p.Link.Data.Data.Value) && p.Link.Link.Data.Data.Value == @"n")))
                    {
                        n += (p.Data.Key == '-' ? -1d : 1d) * (p.Data.Value == @"n" ? 1d : double.Parse(p.Link.Data.Data.Value));
                        s.Remove(pair);
                    }                    //*/
                }
            }
            if (s.Link == null)
            {
                return(s.Clone(new KeyValuePair <char, string>(s.Data.Key,
                                                               sum.ToString(CultureInfo.InvariantCulture)), null));
            }
            if (mult)
            {
                if (!sum.Equals(1d))
                {
                    s.AddFirst(new KeyValuePair <char, string>(/*sum < 1d ? '/' :*/ '*',
                                                               (/*sum < 1d ? 1d / sum : */ sum).ToString(CultureInfo.InvariantCulture)));
                }
            }
            if (!n.Equals(0d))
            {
                string abs = System.Math.Abs(n).ToString(CultureInfo.InvariantCulture);
                var    c   = s.Clone(new KeyValuePair <char, string>(n < 0d ? '-' : '+', abs + @"*n"), null);
                c.Add(new KeyValuePair <char, string>('*', abs));
                c.Add(new KeyValuePair <char, string>('*', @"n"));
                s.Add(c);
            }
            if (!mult)
            {
                //else {
                if (!sum.Equals(0d))
                {
                    s.Add(new KeyValuePair <char, string>(sum < 0d ? '-' : '+',
                                                          System.Math.Abs(sum).ToString(CultureInfo.InvariantCulture)));
                }
            }
            return(s);
        }
Ejemplo n.º 16
0
        public static MultiLinker <KeyValuePair <char, string> > CommonMultiplier(IEnumerable <MultiLinker <KeyValuePair <char, string> > > ss)
        {
            MultiLinker <KeyValuePair <char, string> > r = ArithmeticGraph(One), t;

            if (ss == null)
            {
                return(r);
            }
            var e = ss.GetEnumerator();

            if (!e.MoveNext() || e.Current == null)
            {
                return(r);
            }
            bool minus = false;

            if (EqualsPorN(e.Current.Data.Key, '*', '/'))
            {
                r.Add(e.Current);
            }
            else
            {
                minus = e.Current.Data.Key == '-';
                if (e.Current.Link != null && EqualsPorN(e.Current.Link.Data.Data.Key, '*', '/'))
                {
                    foreach (var mono in e.Current)
                    {
                        r.Add(mono.Data);
                    }
                }
                else
                {
                    r.Add(e.Current.Clone(new KeyValuePair <char, string>('*', e.Current.Data.Value), e.Current.Link));
                }
            }
            while (e.MoveNext())
            {
                t = ArithmeticGraph(One);
                if (e.Current == null)
                {
                    return(t);
                }
                minus &= e.Current.Data.Key == '-';
                if (EqualsPorN(e.Current.Data.Key, '*', '/'))
                {
                    t.Add(e.Current);
                }
                else
                {
                    if (e.Current.Link != null && EqualsPorN(e.Current.Link.Data.Data.Key, '*', '/'))
                    {
                        foreach (var mono in e.Current)
                        {
                            t.Add(mono.Data);
                        }
                    }
                    else
                    {
                        t.Add(e.Current.Clone(new KeyValuePair <char, string>('*', e.Current.Data.Value), e.Current.Link));
                    }
                }
                foreach (var pair in r)
                {
                    var copy = pair.Data;
                    if (!t.Remove(mono => mono != null &&
                                  (mono.Data.Data.Key == copy.Data.Key && EqualsByValue(mono.Data, copy))))
                    {
                        r.Remove(pair);
                    }
                    else if (t.Link == null)
                    {
                        pair.Link = null;
                    }
                }
            }
            return(minus ? ChangeSign(r, '+', '-') : r);
        }
Ejemplo n.º 17
0
 public static string ToString(MultiLinker <KeyValuePair <char, string> > s)
 {
     return(ToString(ToSignedString(s)));
 }
Ejemplo n.º 18
0
 public static MultiLinker <KeyValuePair <char, string> > ChangeSign(MultiLinker <KeyValuePair <char, string> > s, char pstv, char ngtv)
 {
     s.Data = new KeyValuePair <char, string>(s.Data.Key == pstv ? ngtv : pstv, s.Data.Value);
     return(s);
 }