Здоровья всем страждущим. Решил выложить задачу с собеседования и предполагаемый вариант решения.
Индивидуальное задание по упрощенному раскрою пленки
Нужно сделать обработку «Раскрой плёнки», помогающую выбрать оптимальный раскрой.
Есть таблица «Остатки» - заполняется рандомными 5ю разными числами от 1200 до 1600. (НомерСтроки/Ширина)
Есть таблица «Потребности» - заполняется рандомными 10ю разными числами от 250 до 500. (НомерСтроки/Ширина)
Нужно заполнить таблицу «Раскрой». В ней вывести все варианты укладки ширин «Потребностей» на каждую ширину «Остатков». В этой таблице будут следующие колонки:
НомерСтроки;
ШиринаОстатка – ширина из таблицы «Остатки», например «1400»;
КартаРаскроя – вариант списка ширин из таблицы «Потребности», в сумме не превышающий «ШиринуОстатка», например «250+300+350+350»;
ОстатокРаскроя – разность между «ШиринаОстатка» и суммой «КартаРаскроя», напримет «150».
Постараться, чтобы количество кода не превышало 100 строк.
Предполагается, что на решение задачи уйдет не более 3-4 часов.
Код решения:
&НаКлиенте
Процедура ЗаполнитьОстатки(Команда)
ЗаполнитьТаблицуСлучайнымиЧислами(Объект.Остатки, 5, 1200, 1600);
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьПотребности(Команда)
ЗаполнитьТаблицуСлучайнымиЧислами(Объект.Потребности, 10, 250, 500);
КонецПроцедуры
&НаКлиенте
Процедура РассчитатьРаскрой(Команда)
Объект.Раскрой.Очистить();
Для каждого строкаОстатки из Объект.Остатки Цикл
КомбинацииМассивов = РассчитатьКомбинации(строкаОстатки.Ширина);
Для каждого МассивЧисел из КомбинацииМассивов Цикл
СтрокаРаскроя = Объект.Раскрой.Добавить();
СтрокаРаскроя.ШиринаОстатка = строкаОстатки.Ширина;
СтрокаРаскроя.КартаРаскроя = СтрСоединить(МассивЧисел,"+");
СтрокаРаскроя.ОстатокРаскроя = СтрокаРаскроя.ШиринаОстатка - Вычислить(СтрокаРаскроя.КартаРаскроя);
КонецЦикла;
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьТаблицуСлучайнымиЧислами(Таблица, ЧислоСтрок, НижняяГраница, ВерхняяГраница)
Таблица.Очистить();
Генератор = Новый ГенераторСлучайныхЧисел();
Для инд = 1 по ЧислоСтрок Цикл
нСтр = Таблица.Добавить();
нСтр.Ширина = Генератор.СлучайноеЧисло(НижняяГраница, ВерхняяГраница);
КонецЦикла;
КонецПроцедуры
&НаСервере
Функция РассчитатьКомбинации(ИскомоеЗначение)
КомбинацииМассивов = Новый Массив;
МассивСтрок = Новый Массив;
Таб = Объект.Потребности.Выгрузить();
Если Таб.Количество() = 0 Тогда Возврат Новый Массив; КонецЕсли;
Таб.Сортировать("Ширина возр");
минЗначение = Таб[0].Ширина;
Для инд = 0 по Таб.Количество() - 1 Цикл
МассивСтрок.Добавить(Таб[инд]);
Сумма = СуммаМассива(МассивСтрок);
Если Сумма = ИскомоеЗначение ИЛИ (Сумма + минЗначение > ИскомоеЗначение И Сумма < ИскомоеЗначение) Тогда
КомбинацииМассивов.Добавить(МассивСтрокВМассивЧисел(МассивСтрок));
ИначеЕсли Сумма > ИскомоеЗначение Тогда
МассивСтрок.Удалить(МассивСтрок.ВГраница());
инд = Таб.Индекс(МассивСтрок[МассивСтрок.ВГраница()]);
МассивСтрок.Удалить(МассивСтрок.ВГраница());
КонецЕсли;
КонецЦикла;
Возврат КомбинацииМассивов;
КонецФункции
&НаСервереБезКонтекста
Функция СуммаМассива(тМассив)
Сумма = 0;
Для каждого Элемент из тМассив Цикл
Сумма = Сумма + Элемент.Ширина;
КонецЦикла;
Возврат Сумма;
КонецФункции
&НаСервереБезКонтекста
Функция МассивСтрокВМассивЧисел(МассивСтрок)
МассивЧисел = Новый Массив;
Для каждого Элемент из МассивСтрок Цикл
МассивЧисел.Добавить(Элемент.Ширина);
КонецЦикла;
Возврат МассивЧисел;
КонецФункции
Обработка протестирована на конфигурации с версией платформы 8.3.23.2137.