Первая загадка от меня, предложения по улучшению с удовольствием получили!
Сценарий есть; Вы работаете менеджером в рафтинг-компании. Каждое утро вам дают список бронирований, и вы должны сортировать их по плотам. Напишите программу или функцию на выбранном вами языке, которая сделает это за вас.
Каждый плот вмещает максимум n
клиентов, и каждое бронирование рассчитано на группу от 1 до n
человек (включительно). Следующие правила должны быть соблюдены;
Никакие группы не могут быть разделены. Если они забронировали номер вместе, все они должны быть в одном плоту.
Количество плотов должно быть сведено к минимуму.
С учетом двух предыдущих правил группы должны быть как можно более равномерно распределены между плотами.
Входы.
Число n
(вы можете предположить, что это положительное целое число) и размер всех заказов. Это может быть массив, список или аналогичная структура данных, если ваш язык поддерживает такие вещи. Все они будут положительными целыми числами от 1 до n
. Порядок бронирования не определен и не важен.
Выход. Список номеров бронирования, сгруппированных в грузы на плотах. Группировка должна быть указана однозначно, например;
- список или массив массивов.
- разделенный запятыми список для каждого плота. Новая строка между каждым плотом.
Как вы реализуете третье правило, зависит от вас, но это может включать в себя определение средней занятости плота и максимально возможное минимизация отклонений от него. Вот несколько тестов.
n Bookings Output
6 [2,5] [5],[2]
4 [1,1,1,1,1] [1,1,1],[1,1]
6 [2,3,2] [2,2],[3]
6 [2,3,2,3] [2,3],[2,3]
6 [2,3,2,3,2] [2,2,2],[3,3]
12 [10,8,6,4,2] [10],[8,2],[6,4]
6 [4,4,4] [4],[4],[4]
12 [12,7,6,6] [12],[7],[6,6]
Применяются стандартные правила, выигрывает самый короткий код. Веселиться!
Под редакцией; Предлагаемый способ определить как можно более одинаково для третьего правила.
После того, как количество плотов r
было определено (с учетом второго правила), средняя занятость a
может быть рассчитана путем суммирования по бронированию и деления на r
. Для каждого плота отклонение от средней занятости можно найти, используя d(x) = abs(n(x)-a)
, где n(x)
число людей в каждом плоте и 1 <= x <= r
. Для некоторой непрерывной однозначной функции f(y)
, которая является строго положительной и имеет строго положительную первую и неотрицательную вторую производную для всех положительных y
, мы определяем неотрицательную величину F
как сумму всех f(d(x)), 1 <= x <= r
. Любой выбор распределения плота, который удовлетворяет первым двум правилам и F
равен глобальному минимуму, также будет удовлетворять третьему правилу.
g(y) = y
(второй дериват ноль) илиg(y) = y²
(первый дервиат ноль, когдаy = 0
), хотя.Ответы:
Perl 6 ,
163158 байтПопробуйте онлайн!
Как это устроено
Создает все возможные разбиения всех перестановок входного массива.
Фильтрует те, где ни один плот не перебронирован.
Фильтрует те, где количество плотов минимально.
Получает первый с минимальным ∑ (n x -a) 2 .
-4 байта благодаря @ Pietu1998
источник
.abs
если вы возводите в квадрат результат?Haskell 226
228234268байтНаивный ответ в Хаскеле
Или безгольфированный
С некоторыми тестами
Где
test
урожайностьредактировать
Спасибо @flawr и @nimi за совет.
Раздавил
p
немного.Сбрил пару байтов.
источник
s=sum
а затем использоватьs
вместоsum
, и, возможно, вы могли бы также заменитьfst$ ...
на...!!0
.minimumBy(c s)
сhead.sortOn s
и удалить функциюc
. Также:\t->sum t<=n
есть(<=n).sum
.Python3, 224 байта
С тестами:
Как это работает?
p
Функция просто генерирует все разделы данного списка (все возможные способы , чтобы разделить его на подсписки).s=sum
просто переименовывает функцию sum, поэтому последняя строка выполняет всю работу.Я уверен, что это может быть использовано в дальнейшем, особенно
p
функция, но я работал над этим уже часами, так что здесь вы идете.источник