Во время стажировки меня попросили написать программу R5RS, которая создает функцию, скажем, два подмножества. Эта функция должна возвращать #t, если список L содержит два подмножества с одинаковыми суммами элементов и с равным количеством элементов, в противном случае она возвращает #f. Он принимает на вход список L (только положительные числа) и некоторые параметры (которые я считаю полезными. Нет условий на количество параметров), все равные 0 в начале.
Насколько я помню, требования были следующими: - Не определять другие функции и не вызывать их внутри функции "два подмножества". - Он может использовать только следующие конструкции: null?, cond, car, cdr, else, + ,=, not, and, #t, #f, two-subsets (сам для рекурсивного вызова), имена параметров, такие как список, сумма, ... и т. д., числовые константы и круглые скобки.
Были приведены некоторые примеры результатов, которые мы должны были получить, скажем:
(two-subsets '(7 7) 0 0 0) returns #t. The two subsets are {7} and {7}.
(two-subsets '(7 7 1) 0 0) returns #t. The two subsets are {7} and {7}.
(two-subsets '(5 3 2 4) 0 0) returns #t. The two subsets are {2, 5} and {3, 4}.
(two-subsets '(1 2 3 6 9) 0 0) returns #f.
Я начал с того, что написал подпись, которая, как мне кажется, должна быть примерно такой:
(define two-subsets (lambda (L m n ... other parameters)
(cond
Проблема действительно сложная, и ее сложность явно превышает O(n), я читал об этом на https://en.wikipedia.org/wiki/Partition_problem .
Я попытался начать с определения алгоритма, прежде чем кодировать его. Я подумал о том, чтобы взять в качестве параметров: сумму списка L, поэтому в моих условиях я буду перебирать только те комбинации, сумма которых равна ‹= sum(L)/2. Делая это, я могу немного уменьшить сложность проблемы, но все же я не мог понять, как это сделать.
Это выглядит как интересная проблема, и я действительно хочу узнать о ней больше.