Если у кого-то будет время, подскажите, пожалуйста, в чем может быть проблема в processVideos(). Старался расписать методы по ссылке из комментариев на задачу о рюкзаке. Но на 16 задаче тест не прошел именно из-за этого метода.
Заранее спасибо
public void processVideos(){
if (storage.list().size() == 0){ //Если нет рекламных видео, которые можно показать посетителю
throw new NoVideoAvailableException();
}
else {
List<Advertisement> adList = getAdsWithHits(storage.list());
MakeAllSets(adList);
sortAds(bestListSet);
EventDataRow event = new VideoSelectedEventDataRow(bestListSet, bestPrice, CalcTime(bestListSet));
StatisticManager.getInstance().register(event);//регистрация события "видео выбрано" перед отображением рекламы пользователю
showAds(bestListSet);
}
}
private void sortAds(List<Advertisement> ads){
ads.sort(Comparator.comparingLong(Advertisement::getAmountPerOneDisplaying).reversed().thenComparing(ad -> ad.getAmountPerOneDisplaying() * 1000 / ad.getDuration()));//сортировка в порядке уменьшения стоимости показа одного рекламного ролика в копейках
//после сортировка по увеличению стоимости показа одной секунды рекламного ролика в тысячных частях копейки
}
private void showAds(List<Advertisement> ads){//Отобразить все рекламные ролики. для каждого показа сделать ревалидейт!
for (Advertisement ad : ads) {
ConsoleHelper.writeMessage(String.format("%s is displaying... %d, %d", ad.getName(), ad.getAmountPerOneDisplaying(), ad.getAmountPerOneDisplaying() * 1000 / ad.getDuration()));
ad.revalidate();
}
}
private List<Advertisement> getAdsWithHits (List<Advertisement> ads){ //выбираем только те рекламные ролики, в которых количество показов(hits) > 0. Чтобы не создавать дополнительный геттер, сделал это через getAmountPerOneDisplaying
return ads.stream().filter((ad) -> ad.getAmountPerOneDisplaying() > 0).collect(Collectors.toList());
}
private void MakeAllSets (List<Advertisement> ads){//создание всех наборов перестановок и их проверка. По итогу отработки метода в bestListOrder будет наилучший набор.
if (ads.size() > 0)
CheckList(ads);
if (CalcTime(ads) > timeSeconds) {//Иначе зачем, ведь все ролики помещаются, а цена будет становится только меньше. Но изначально этого пункта по ссылке vscode не было
for (int i = 0; i < ads.size(); i++) {
List<Advertisement> newAds = new ArrayList<>(ads);
newAds.remove(i);
MakeAllSets(newAds);
}
}
}
private void CheckList (List<Advertisement> ads){//проверяем, является ли список лучшим
if (CalcTime(ads) <= timeSeconds) { //если продолжительность набора роликов меньше времени готовки блюд, то проавливаемся во внутрь. Иначе этот набор нам не подходит.
if (CalcPrice(ads) > bestPrice) {
bestListSet = ads;
bestPrice = CalcPrice(ads);
}
else if (CalcPrice(ads) == bestPrice) { //если цена за ролики равна
if (CalcTime(ads) > CalcTime(bestListSet))//выбираем набор роликов с максимальной продолжительностю
bestListSet = ads;
else if (CalcTime(ads) == CalcTime(bestListSet)) {//если цена и продолжительность набора роликов равна
if (ads.size() < bestListSet.size()) //то выбираем вариант с минимальным количеством роликов в наборе
bestListSet = ads;
}
}
}
}
private long CalcPrice (List<Advertisement> ads){
return ads.stream().mapToLong(Advertisement::getAmountPerOneDisplaying).sum();
}
private int CalcTime (List<Advertisement> ads){
return ads.stream().mapToInt(Advertisement::getDuration).sum();
}