Пример #1
0
        public void SmartGetChangeTest()
        {
            ConfiguireIoc <SmartGetChangeAlgorithm>();

            // Создаем модель с расчетом на то, что исходное состояние уже содержит нужное количество монет разных номиналов (исходные данные из БТ).
            // Если такой уверенности нет - значит нужно было бы здесь заполнить модель исходными значениями.
            var model = new VendingMachineModel();

            // Опускаем в машину 8 рублей (неважно какими монетами)
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);

            // Запрашиваем сдачу
            var change = model.GetChange();
            // Проверяем - какими монетами выдана сдача
            var changeUserCoins = change.ToDictionary(o => o.Value, o => o.Count);

            Assert.AreEqual(1, changeUserCoins.ContainsKey(5) ? changeUserCoins[5] : (int?)null);
            Assert.AreEqual(1, changeUserCoins.ContainsKey(2) ? changeUserCoins[2] : (int?)null);
            Assert.AreEqual(1, changeUserCoins.ContainsKey(1) ? changeUserCoins[1] : (int?)null);

            // Снова опускаем в машину 8 рублей (неважно какими монетами)
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);
            // Эмулируем ситуацию, когда в кошельке машины нет монет по 1р
            model.VmPurse
            .Where(o => o.Value == 1)
            .ToList()
            .ForEach(o =>
            {
                o.Count = 0;
            });
            // Запрашиваем сдачу
            change = model.GetChange();
            // Проверяем - какими монетами выдана сдача
            changeUserCoins = change.ToDictionary(o => o.Value, o => o.Count);
            Assert.AreEqual(4, changeUserCoins.ContainsKey(2) ? changeUserCoins[2] : (int?)null);

            // Снова опускаем в машину 2 рубля (неважно какими монетами)
            model.ReplenishDeposit(2);
            // Эмулируем ситуацию, когда в кошельке машины нет монет по 1р и 2р
            model.VmPurse
            .Where(o => o.Value < 3)
            .ToList()
            .ForEach(o =>
            {
                o.Count = 0;
            });
            // Запрашиваем сдачу - умный алгоритм выдаст ошибку
            change = model.GetChange();
            Assert.IsNull(change);
            Assert.IsTrue(!string.IsNullOrEmpty(model.Message));
        }
Пример #2
0
        public async Task <IActionResult> Index()
        {
            var model = new VendingMachineModel()
            {
                Products = await _context.Products.ToListAsync(),
                Cashes   = await _context.Cashes.ToListAsync()
            };

            return(View(model));
        }
        public bool Contains(VendingMachineModel model)
        {
            sqlUnitOfWork.InsertRecord(new VendingMachineDataMapper().MapFromDomain(model));
            sqlUnitOfWork.InsertRecord(new LocationDataMapper().MapFromDomain(model));
            foreach (CellModel cell in model.Cells)
            {
                sqlUnitOfWork.InsertRecord(new CellDataMapper().MapFromDomain(cell));
            }

            throw new NotImplementedException();
        }
        public int DeleteModel(VendingMachineModel model, bool commit = false)
        {
            sqlUnitOfWork.DeleteRecord(DataBaseServices.LocationTableName, "VendingMachineId", model.Id);
            sqlUnitOfWork.DeleteRecord(DataBaseServices.CellTableName, "VendingMachineId", model.Id);
            sqlUnitOfWork.DeleteRecord(DataBaseServices.VendingMachineTableName, "Id", model.Id);

            if (commit)
            {
                Commit();
            }
            return(0);
        }
        public void AddModel(VendingMachineModel model, bool commit = false)
        {
            sqlUnitOfWork.InsertRecord(new VendingMachineDataMapper().MapFromDomain(model));
            sqlUnitOfWork.InsertRecord(new LocationDataMapper().MapFromDomain(model));
            foreach (CellModel cell in model.Cells)
            {
                sqlUnitOfWork.InsertRecord(new CellDataMapper().MapFromDomain(cell));
            }

            if (commit)
            {
                Commit();
            }
        }
        public int UpdateModel(VendingMachineModel model, bool commit = false)
        {
            sqlUnitOfWork.UpdateRecord(new VendingMachineDataMapper().MapFromDomain(model), "Id", model.Id);
            sqlUnitOfWork.UpdateRecord(new LocationDataMapper().MapFromDomain(model), "VendingMachineId", model.Id);
            foreach (CellModel cell in model.Cells)
            {
                sqlUnitOfWork.UpdateRecord(new CellDataMapper().MapFromDomain(cell), "VendingMachineId", model.Id);
            }

            if (commit)
            {
                Commit();
            }
            return(0);
        }
        //private readonly int[] coins = new int[] { 1, 2, 5, 10 };


        /// <summary>
        /// Подобрать сдачу минимальным количеством монет
        /// </summary>
        public List <CoinsArray> Process(VendingMachineModel model)
        {
            this.coins = model.VmPurse
                         .Where(o => o.Count > 0)
                         .Select(o => o.Value)
                         .OrderBy(o => o)
                         .ToArray();

            // Получаем все возможные наборы монет для формирования нужной суммы
            var results = new List <ChangeCoinsList>();

            Process(model.Deposit, 0, null, results);
            // Сортируем по возрастанию количества монет, а затем по убыванию самой большой монеты
            results = results
                      .OrderBy(o => o.Coins.Count)
                      .ThenBy(o => o.Coins.Last())
                      .ToList();

            // Отсекаем те наборы монет, которые не могут быть получены из текущего кошелька машины
            var firstCoinsArrays = results
                                   .Select(o =>
            {
                var coinsArrays = o.Coins
                                  .GroupBy(c => c)
                                  .Select(c => new CoinsArray(c.Key, c.Count()))
                                  .ToList();
                return(coinsArrays);
            })
                                   .Where(o =>
            {
                foreach (var coinsArray in o)
                {
                    //if (!model.VmPurse.Any(x => x.Value == coinsArray.Value && x.Count < coinsArray.Count))
                    if (!model.VmPurse.Any(x => x.Value == coinsArray.Value && x.Count >= coinsArray.Count))
                    {
                        // Если монет какого-то номинала не хватает в кошельке машины - значит данный набор монет не подходит
                        return(false);
                    }
                }
                return(true);
            })
                                   .FirstOrDefault();

            // Анализируем результат работы алгоритма
            // Если firstCoinsArrays == null - значит алгоритм не отработал
            // Иначе - если вся сумма распределена по монетам - переносим эти монеты из кошелька машины в кошелек пользователя
            return(firstCoinsArrays);
        }
Пример #8
0
        public void GreedyGetChangeTest()
        {
            ConfiguireIoc <GreedyGetChangeAlgorithm>();

            // Для определения минимального количества монет для сдачи используем "жадный алгоритм".
            // Т.к. у нас монеты достоинством 10,5,2,1 - он подходит.
            // Недостаток алгоритма - не всегда будет работать при недостатке некоторых монет в машине.
            // Пример: 8 рублей можно выдать 5+2+1 или 2+2+2+2. Жадный алгоритм выдаст первый вариант.
            // Но если в машине нет рублевых монет - жадный алгоритм не найдет решение.

            // Создаем модель с расчетом на то, что исходное состояние уже содержит нужное количество монет разных номиналов (исходные данные из БТ).
            // Если такой уверенности нет - значит нужно было бы здесь заполнить модель исходными значениями.
            var model = new VendingMachineModel();

            // Опускаем в машину 8 рублей (неважно какими монетами)
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);

            // Запрашиваем сдачу
            var change = model.GetChange();
            // Проверяем - какими монетами выдана сдача
            var changeUserCoins = change.ToDictionary(o => o.Value, o => o.Count);

            Assert.AreEqual(1, changeUserCoins.ContainsKey(5) ? changeUserCoins[5] : (int?)null);
            Assert.AreEqual(1, changeUserCoins.ContainsKey(2) ? changeUserCoins[2] : (int?)null);
            Assert.AreEqual(1, changeUserCoins.ContainsKey(1) ? changeUserCoins[1] : (int?)null);

            // Снова опускаем в машину 8 рублей (неважно какими монетами)
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);
            model.ReplenishDeposit(2);
            // Эмулируем ситуацию, когда в кошельке машины нет монет по 1р
            model.VmPurse
            .Where(o => o.Value == 1)
            .ToList()
            .ForEach(o =>
            {
                o.Count = 0;
            });
            // Запрашиваем сдачу - жадный алгоритм выдаст ошибку
            change = model.GetChange();
            Assert.IsNull(change);
            Assert.IsTrue(!string.IsNullOrEmpty(model.Message));
        }
        /// <summary>
        /// Подобрать сдачу минимальным количеством монет
        /// </summary>
        public List <CoinsArray> Process(VendingMachineModel model)
        {
            // Для определения минимального количества монет для сдачи используем "жадный алгоритм".
            // Т.к. у нас монеты достоинством 10,5,2,1 - он подходит.
            // Недостаток алгоритма - не всегда будет работать при недостатке некоторых монет в машине.
            // Пример: 8 рублей можно выдать 5+2+1 или 2+2+2+2. Жадный алгоритм выдаст первый вариант.
            // Но если в машине нет рублевых монет - жадный алгоритм не найдет решение.

            var deposit = model.Deposit;
            var vmPurse = model.VmPurse
                          .Where(o => o.Count > 0)
                          .OrderByDescending(o => o.Value)
                          .ToList();
            var change = new List <CoinsArray>();

            // Жадный алгоритм
            foreach (var coinsArray in vmPurse)
            {
                var nominal    = coinsArray.Value;
                var coinsCount = coinsArray.Count;
                if (nominal <= deposit)
                {
                    var changeCoinsCount = Convert.ToInt32(Math.Floor((deposit + 0.0) / nominal));
                    if (changeCoinsCount > coinsCount)
                    {
                        changeCoinsCount = coinsCount;
                    }

                    change.Add(new CoinsArray(nominal, changeCoinsCount));
                    deposit = deposit % nominal;
                }
            }

            // Анализируем результат работы алгоритма
            if (deposit > 0)
            {
                // Если после перебора не вся сумма распределена по монетам - значит алгоритм не отработал
                return(null);
            }
            else
            {
                // Если вся сумма распределена по монетам - переносим эти монеты из кошелька машины в кошелек пользователя
                return(change);
            }
        }
        public VendingMachineModel FindById(int id)
        {
            VendingMachineModel       vm       = new VendingMachineModel();
            VendingMachineTableRecord vmRecord = sqlUnitOfWork.FindById <VendingMachineTableRecord>(DataBaseServices.VendingMachineTableName, "Id", id);

            new VendingMachineDataMapper().MapFromTable(ref vm, vmRecord);

            LocationTableRecord locationRecord = sqlUnitOfWork.FindById <LocationTableRecord>(DataBaseServices.VendingMachineTableName, "VendingMachineId", vm.Id);

            new LocationDataMapper().MapFromTable(ref vm, locationRecord);

            IEnumerable <CellTableRecord> cells = sqlUnitOfWork.FindAll <CellTableRecord>(DataBaseServices.CellTableName, "VendingMachineId", vm.Id);

            foreach (CellTableRecord cell in cells)
            {
                CellModel cellModel = new CellModel();
                new CellDataMapper().MapFromTable(ref cellModel, cell);
                vm.Cells.Add(cellModel);
            }

            return(vm);
        }