コード例 #1
0
        private ConversionPath GetShortestPath(ToConvert toConvert, List <ExchangeRate> exchangeRates)
        {
            // keys are currencies, values are for the chained calculations
            // first node: <initial currency, amount>
            // other nodes: <currency, exchange rate>
            var firstNode = new KeyValuePair <string, float>(toConvert.InitialCurrency, toConvert.Amount);

            // init with a first path with the currency to convert from
            var possibilities = new List <ConversionPath> {
                new ConversionPath {
                    Nodes = new List <KeyValuePair <string, float> > {
                        firstNode
                    }
                }
            };

            while (exchangeRates.Any())
            {
                foreach (var possibility in possibilities.ToList())
                {
                    var lastNode = possibility.Nodes.Last();

                    var matchingRates = exchangeRates
                                        .Where(e => lastNode.Key == e.InitialCurrency || lastNode.Key == e.TargetCurrency)
                                        .ToList();

                    if (matchingRates.Any())
                    {
                        possibilities = AddPathsFromMatches(possibilities, possibility, matchingRates);

                        var shortest = possibilities.FirstOrDefault(p => p.Nodes.Last().Key == toConvert.TargetCurrency);
                        // found the shortest path
                        if (shortest != null)
                        {
                            return(shortest);
                        }

                        exchangeRates.RemoveAll(e => matchingRates.Contains(e));
                    }
                    else
                    {
                        // no match, useless path
                        possibilities.Remove(possibility);
                        // remaining exchange rates but no path to solution
                        if (!possibilities.Any())
                        {
                            return(null);
                        }
                        break;
                    }
                }
            }
            // empty list but no solution found
            return(null);
        }
コード例 #2
0
        public void Run(string filePath)
        {
            if (!File.Exists(filePath))
            {
                Console.Error.WriteLine("File path doesn't exist");
                Environment.Exit(1);
            }

            var lines = File.ReadLines(filePath).ToList();

            try
            {
                var instructions = ExchangeRatesTableParser.GetConversionInstructions(lines[0], lines[1]);

                ToConvert toConvert          = instructions.Item1;
                int       exchangeRatesCount = instructions.Item2;

                var exchangeRates = ExchangeRatesTableParser.ParseRates(lines, exchangeRatesCount);

                ConversionPath shortestPath = GetShortestPath(toConvert, exchangeRates.ToList());

                if (shortestPath == null)
                {
                    Console.Error.WriteLine("Incorrect file: no solution");
                    Environment.Exit(1);
                }

                Console.WriteLine(Math.Round(ConvertCurrency(shortestPath)));
            }
            catch (IndexOutOfRangeException)
            {
                Console.Error.WriteLine("Incorrect file: doesn't respect the exchange rates format");
                Environment.Exit(1);
            }
            catch (FormatException)
            {
                Console.Error.WriteLine("Incorrect file: number of lines not provided");
                Environment.Exit(1);
            }
            catch (IncorrectRateCountException)
            {
                Console.Error.WriteLine("Incorrect file: expected number of exchange rates differs from content");
                return;
            }
        }
コード例 #3
0
        public static Tuple <ToConvert, int> GetConversionInstructions(string request, string exchangeRateCount)
        {
            string[] requestData = request.Split(';');

            if (requestData.Length != 3)
            {
                throw new IndexOutOfRangeException();
            }
            else
            {
                ToConvert toConvert = new ToConvert {
                    InitialCurrency = requestData[0],
                    Amount          = Convert.ToInt32(requestData[1]),
                    TargetCurrency  = requestData[2]
                };
                int count = Convert.ToInt32(exchangeRateCount);
                return(Tuple.Create(toConvert, count));
            }
        }
コード例 #4
0
        private static IEnumerable <object> GetImpls()
        {
            var sourceType      = typeof(TSource);
            var destinationType = typeof(TDestination);

            // Custom
            foreach (var factory in InternalConvert.factories)
            {
                yield return(factory.GetConverter(sourceType, destinationType));
            }

            // Basic
            yield return(BasicConvert.Instance);

            // Implicit
            if (sourceType == destinationType)
            {
                yield return(new EqualsConvert <TSource>());
            }

            // Implicit
            if (Nullable.GetUnderlyingType(destinationType) == sourceType)
            {
                yield return(Activator.CreateInstance(typeof(StructToNullableConvert <>).MakeGenericType(sourceType)));
            }

            // Explicit
            if (Nullable.GetUnderlyingType(sourceType) == destinationType)
            {
                yield return(Activator.CreateInstance(typeof(NullableToStructConvert <>).MakeGenericType(destinationType)));
            }

            // Custom
            if (destinationType == typeof(string))
            {
                yield return(new ToStringConvert <TSource>());
            }

            // Implicit
            if (destinationType.IsAssignableFrom(sourceType))
            {
                yield return(Activator.CreateInstance(typeof(AssignableConvert <,>).MakeGenericType(sourceType, destinationType)));
            }

            // Custom
            if (sourceType == typeof(DBNull))
            {
                yield return(new FromDBNullConvert <TDestination>());
            }

            // Custom
            if (destinationType == typeof(DBNull))
            {
                yield return(new ToDBNullConvert <TSource>());
            }

            // Implicit & XConvert
            {
                if (Nullable.GetUnderlyingType(sourceType) is Type underlyingType && underlyingType != sourceType)
                {
                    yield return(Activator.CreateInstance(typeof(NullableToValueConvert <,>).MakeGenericType(underlyingType, destinationType)));
                }
            }

            // XConvert & Implicit
            {
                if (Nullable.GetUnderlyingType(destinationType) is Type underlyingType && underlyingType != destinationType)
                {
                    yield return(Activator.CreateInstance(typeof(ValueToNullableConvert <,>).MakeGenericType(sourceType, underlyingType)));
                }
            }

            // Custom
            if (sourceType == typeof(string) && destinationType.IsEnum)
            {
                yield return(Activator.CreateInstance(typeof(ParseEnum <>).MakeGenericType(destinationType)));
            }

            // Implicit
            if (ImplicitConvert.TryGetMathod(sourceType, destinationType, out var method))
            {
                yield return(BaseDynamicConvert.CreateInstanceByIL <TSource, TDestination>(method));
            }

            // Explicit
            if (ExplicitConvert.TryGetMathod(sourceType, destinationType, out method))
            {
                yield return(BaseDynamicConvert.CreateInstanceByIL <TSource, TDestination>(method));
            }

            // Custom
            if (ParseConvert.TryGetMathod(sourceType, destinationType, out method))
            {
                yield return(BaseDynamicConvert.CreateInstanceByIL <TSource, TDestination>(method));
            }

            // Custom
            if (ToConvert.TryGetMathod(sourceType, destinationType, out method))
            {
                yield return(BaseDynamicConvert.CreateInstanceByIL <TSource, TDestination>(method));
            }

            // Custom
            if (ConstructorConvert.TryGetMathod(sourceType, destinationType, out var constructor))
            {
                yield return(BaseDynamicConvert.CreateInstanceByIL <TSource, TDestination>(constructor));
            }

            // Explicit
            if (sourceType.IsAssignableFrom(destinationType))
            {
                yield return(Activator.CreateInstance(typeof(BaseConvert <,>).MakeGenericType(sourceType, destinationType)));
            }

            // Error
            yield return(new ForceConvert <TSource, TDestination>());
        }