public Formula GetTargetCharInfo(char Target)
 {
     return(new Formula(
                NumMonof.Select(x => x.GetTargetCharInfo(Target)).ToList(),
                DenMonof.Select(x => x.GetTargetCharInfo(Target)).ToList()
                ));
 }
        public override int GetHashCode()
        {
            var hash = 1;

            if (NumMonof.Count() != 0)
            {
                hash ^= NumMonof.Select(x => x.GetHashCode()).Aggregate((now, next) => now ^ next);
            }
            if (DenMonof.Count() != 0)
            {
                hash ^= DenMonof.Select(x => - x.GetHashCode()).Aggregate((now, next) => now ^ next);
            }

            return(hash);
        }
 public async Task <double> ToDouble()
 {
     return((await NumMonof.Select(async x => await x.ToDouble()).WhenAll()).Aggregate((now, next) => now + next)
            / (await DenMonof.Select(async x => await x.ToDouble()).WhenAll()).Aggregate((now, next) => now + next));
 }
 public Formula RemoveX(char target)
 {
     return(new Formula(NumMonof.Select(x => x.RemoveX(target)).ToList(), DenMonof.Select(x => x.RemoveX(target)).ToList()));
 }
 public async Task <Formula> SubstituteX(char target, double value)
 {
     return(new Formula((await NumMonof.Select(async x => await x.SubstituteX(target, value)).WhenAll()).ToList(),
                        (await DenMonof.Select(async x => await x.SubstituteX(target, value)).WhenAll()).ToList()));
 }
 /// <summary>
 /// 文字に代入して数値を得る
 /// </summary>
 /// <param name="dics"></param>
 /// <returns></returns>
 public async Task <Formula> Substitute(Dictionary <char, double> dics)
 {
     return(new Formula((await NumMonof.Select(async x => await x.Substitute(dics)).WhenAll()).ToList(),
                        (await DenMonof.Select(async x => await x.Substitute(dics)).WhenAll()).ToList()));
 }
        public async Task <string> GetString(bool ReturnFraction = false, bool ForDisplay = false)
        {
            string NumStr = "";

            if (NumMonof.Count() == 0)
            {
                return("0");
            }
            else
            {
                NumStr = (await NumMonof.Select(async x =>
                {
                    var str = await x.GetString(ReturnFraction, ForDisplay);
                    if (str == "")
                    {
                        return("");
                    }
                    else if (str.First() == '-')
                    {
                        return(str);
                    }
                    else
                    {
                        return("+" + str);
                    }
                }).WhenAll()).Aggregate((now, next) => now + next);

                if (NumStr != "" && NumStr.First() == '+')
                {
                    NumStr = NumStr.Substring(1);
                }
            }

            if (DenMonof.Count() == 1 && DenMonof[0].IsOne())
            {
                return(NumStr);
            }
            else
            {
                var DenStr = (await DenMonof.Select(async x =>
                {
                    var str = await x.GetString(ReturnFraction, ForDisplay);
                    if (str == "")
                    {
                        return("");
                    }
                    else if (str.First() == '-')
                    {
                        return(str);
                    }
                    else
                    {
                        return("+" + str);
                    }
                }).WhenAll()).Aggregate((now, next) => now + next);

                if (DenStr != "" && DenStr.First() == '+')
                {
                    DenStr = DenStr.Substring(1);
                }

                if (DenStr == "1" || DenStr == "")
                {
                    return(NumStr);
                }

                if (NumStr.Contains("+") || NumStr.Substring(1).Contains("-"))
                {
                    NumStr = "(" + NumStr + ")";
                }
                if (DenStr.Contains("+") || DenStr.Substring(1).Contains("-"))
                {
                    DenStr = "(" + DenStr + ")";
                }

                return(NumStr + "/" + DenStr);
            }
        }
        /// <summary>
        /// 約分する
        /// </summary>
        private void Reduction()
        {
            var factors = Factorizations.FactorOut(this);

            NumMonof = (factors.Item1.GetNumerator() * factors.Item2.GetNumerator()).NumMonof;
            DenMonof = (factors.Item1.GetDenominator() * factors.Item2.GetDenominator()).NumMonof;

            if (DenMonof.Count() == 1)//分母が一つだけであれば数字は上につける
            {
                NumMonof           = NumMonof.Select(x => x / DenMonof[0].Number.ToDouble()).ToList();
                DenMonof[0].Number = 1;
                return;
            }
            else//上下の式がどちらかの因数である場合は、割り切る
            {
                var  chars  = this.GetCharDics().Keys.ToList();
                char target = '0';
                if (chars.Count() == 0)
                {
                    return;
                }
                if (chars.Count() == 1)
                {
                    target = chars[0];
                }
                else
                {
                    var chardic = chars.ToDictionary(x => x, x => NumMonof.Concat(DenMonof).Max(y => y.Character.ContainsKey(x) ? y.Character[x] : 0));
                    target = chardic.First().Key;
                    foreach (var dic in chardic)
                    {
                        if (dic.Key != target)
                        {
                            if (dic.Value > chardic[target])
                            {
                                target = dic.Key;
                            }
                            else if (dic.Value == chardic[target])
                            {
                                if (dic.Key.CompareTo(target) < 0)
                                {
                                    target = dic.Key;
                                }
                            }
                        }
                    }
                }

                var IsNumBigger = NumMonof.Max(x => x.Character.ContainsKey(target) ? x.Character[target] : 0)
                                  > DenMonof.Max(x => x.Character.ContainsKey(target) ? x.Character[target] : 0);


                var Bigger   = new Dictionary <int, List <Monomial> > {
                };
                var Smaller  = new Dictionary <int, List <Monomial> > {
                };
                var BiggerF  = new List <Monomial> {
                };
                var SmallerF = new List <Monomial> {
                };


                if (IsNumBigger)
                {
                    BiggerF  = NumMonof;
                    SmallerF = DenMonof;

                    Bigger  = NumMonof.GroupBy(x => x.Character.ContainsKey(target) ? x.Character[target] : 0).ToDictionary(x => x.Key, x => x.Select(y => y).ToList());
                    Smaller = DenMonof.GroupBy(x => x.Character.ContainsKey(target) ? x.Character[target] : 0).ToDictionary(x => x.Key, x => x.Select(y => y).ToList());
                }
                else
                {
                    BiggerF  = DenMonof;
                    SmallerF = NumMonof;

                    Bigger  = DenMonof.GroupBy(x => x.Character.ContainsKey(target) ? x.Character[target] : 0).ToDictionary(x => x.Key, x => x.Select(y => y).ToList());
                    Smaller = NumMonof.GroupBy(x => x.Character.ContainsKey(target) ? x.Character[target] : 0).ToDictionary(x => x.Key, x => x.Select(y => y).ToList());
                }

                if (Smaller.Any(x => x.Value.Count() != 1))
                {
                    return;
                }

                var SUMfactor = new List <Monomial> {
                };


                var BiggerMax  = Bigger.Keys.Max();
                var SmallerMax = Smaller.Keys.Max();

                while (true)
                {
                    var factor = Bigger[BiggerMax].Select(x => x / Smaller[SmallerMax][0]).ToList();
                    SUMfactor = SUMfactor.Concat(factor).ToList();

                    BiggerF   = (new Formula(BiggerF) - new Formula(SmallerF) * new Formula(factor)).NumMonof;
                    Bigger    = BiggerF.GroupBy(x => x.Character.ContainsKey(target) ? x.Character[target] : 0).ToDictionary(x => x.Key, x => x.Select(y => y).ToList());
                    BiggerMax = Bigger.Keys.Max();

                    if (BiggerF.Count() == 0)
                    {
                        var res = new Formula(SUMfactor);

                        NumMonof = res.NumMonof;
                        DenMonof = res.DenMonof;

                        return;
                    }
                    else if (BiggerMax < SmallerMax)
                    {
                        return;
                    }
                }
            }
        }