Пример #1
0
        private void GetMinPrice(TrolleyCalculatorInput input, decimal maxPrice, List <Special> specials, Dictionary <string, long> shoppedProducts, ref decimal minPrice, int i, ref bool minPriceUpdated, int j)
        {
            var specialCounts = new List <int>();

            specialCounts.InitList(i, specials.Count);
            var more = true;

            for (var k = j; more; ++k)
            {
                int oldValue = specialCounts[j];
                specialCounts[j] = oldValue + k;
                if (this.IsApplicable(shoppedProducts, specials, specialCounts))
                {
                    var priceForSpecials = this.GetPriceForSpecials(specials, specialCounts);
                    if (maxPrice > priceForSpecials)
                    {
                        var priceForRest = this.GetPriceForNonSpecials(input.Products, specials, specialCounts, shoppedProducts);
                        var price        = priceForSpecials + priceForRest;
                        if (price < minPrice)
                        {
                            minPrice        = price;
                            minPriceUpdated = true;
                        }

                        specialCounts[j] = oldValue;
                    }
                }
                else
                {
                    more = false;
                }
            }
        }
Пример #2
0
        public void TestGetMinPriceWith0()
        {
            var service = new ProductService(new MockResourceService());
            var input   = new TrolleyCalculatorInput()
            {
                Products = new List <Product>()
                {
                    new Product {
                        Name = MockResourceService.ProductNameA, Price = 0
                    }
                },
                Quantities = new List <Product>()
                {
                    new Product {
                        Name = MockResourceService.ProductNameA, Quantity = 0
                    }
                },
                Specials = new List <Special>()
                {
                    new Special
                    {
                        Total      = 5,
                        Quantities = new List <Product>()
                        {
                            new Product {
                                Name = MockResourceService.ProductNameA, Quantity = 0
                            }
                        }
                    }
                }
            };

            Assert.AreEqual(service.GetMinPrice(input).Total, 0);
            Assert.AreEqual(service.GetMinPriceAsDecimal(input), 0);
        }
Пример #3
0
        /// <summary>
        /// Returns the lowest possible total based on provided lists of prices, specials and quantities.
        /// </summary>
        /// <param name="input">An instance of TrolleyCalculatorInput with prices, specials and quantities</param>
        /// <returns>An instance of TrolleyCalculatorOutput with the lowest possible total</returns>
        public TrolleyCalculatorOutput GetMinPrice(TrolleyCalculatorInput input)
        {
            if (input == null)
            {
                return(this.CreateTrolleyCalculatorOutput(0));
            }

            var maxPrice = this.GetMaxPrice(input);

            if (maxPrice == 0)
            {
                return(this.CreateTrolleyCalculatorOutput(0));
            }

            var specials        = this.GetApplicableSpecials(input, maxPrice);
            var shoppedProducts = this.GetShoppedProducts(input);
            var minPrice        = maxPrice;
            var i = 0;
            var minPriceUpdated = false;

            while (!minPriceUpdated)
            {
                minPriceUpdated = false;
                for (var j = 0; j < specials.Count; ++j)
                {
                    this.GetMinPrice(input, maxPrice, specials, shoppedProducts, ref minPrice, i, ref minPriceUpdated, j);
                }

                i++;
            }

            return(this.CreateTrolleyCalculatorOutput(minPrice));
        }
Пример #4
0
        private List <Special> GetApplicableSpecials(TrolleyCalculatorInput input, decimal maxPrice)
        {
            // The price is less than the max price when buying the individual items.
            var result = input.Specials.Where(s => s.Total < maxPrice).ToList();

            // Should not to have any products that are not in the shopping cart.
            var shoppedProductNames = input.Quantities.Select(q => q.Name).ToList();

            result = result.Where(s => s.Quantities.All(q => shoppedProductNames.Contains(q.Name))).ToList();

            // Should not to have more products than the requested quantity.
            var shoppedProductQuntities = input.Quantities.ToDictionary(q => q.Name, q => q.Quantity);

            return(result.Where(s => s.Quantities.All(q => { shoppedProductQuntities.TryGetValue(q.Name, out long v); return v >= q.Quantity; })).ToList());
        }
Пример #5
0
        private decimal GetMaxPrice(TrolleyCalculatorInput input)
        {
            decimal price = 0;

            foreach (Product quantity in input.Quantities)
            {
                foreach (Product product in input.Products)
                {
                    if (product.Name == quantity.Name)
                    {
                        price += quantity.Quantity * product.Price;
                        break;
                    }
                }
            }

            return(price);
        }
Пример #6
0
 /// <summary>
 /// Returns the lowest possible total based on provided lists of prices, specials and quantities.
 /// </summary>
 /// <param name="input">An instance of TrolleyCalculatorInput with prices, specials and quantities</param>
 /// <returns>The lowest possible total as decimal</returns>
 public decimal GetMinPriceAsDecimal(TrolleyCalculatorInput input) => (decimal)this.GetMinPrice(input).Total;
Пример #7
0
 private Dictionary <string, long> GetShoppedProducts(TrolleyCalculatorInput input)
 {
     return(input.Quantities.ToDictionary(q => q.Name, q => q.Quantity));
 }