Раздать по две карты с равной суммой - Lisp
Формулировка задачи:
Задача из раздела "Форум C# для начинающих":
Решение задачи по раздаче карт с числами
Решение задачи: «Раздать по две карты с равной суммой»
textual
Листинг программы
(defun cards (x) (let ((tab (make-hash-table)) (m (* 2 (/ (apply '+ x) (length x))))) (labels ((razbor (x y i) (cond ((null x) y) ((gethash (car x) tab) (setq y (cons (list (gethash (car x) tab) i) y)) (remhash (car x) tab) (razbor (cdr x) y (1+ i))) (t (setf (gethash (- m (car x)) tab) i) (razbor (cdr x) y (1+ i)))))) (razbor x nil 1))))
Объяснение кода листинга программы
В данном коде:
- Создаётся функция
cardsс одним аргументомx. - Внутри функции создаётся пустая таблица хеш-функций с помощью
make-hash-table. - Вычисляется значение переменной
mкак произведение двух чисел: двойки и результата вычисления выражения(apply '+ x) / (length x). - Создаются метки для внутреннего блока
labels, который будет выполнять основную работу. - Внутри блока
labelsопределяется вспомогательная функцияrazbor. - Вспомогательная функция
razborпринимает три аргумента:x,yиi. - Если
xравноnil, тоyвозвращается без изменений. - Если ключ
car xприсутствует в таблице хеш-функций, то к значению этого ключа добавляется новая запись(cons (list (gethash (car x) tab) i) y). - Если ключ
car xотсутствует в таблице хеш-функций, то к значению ключа(- m (car x))добавляется новая запись(cons (list (gethash (- m (car x)) tab) i) y). - Если
xне являетсяnil, то выполняется рекурсивный вызов вспомогательной функцииrazborс аргументами(cdr x)и(1+ i). - В основной функции
cardsвызывается вспомогательная функцияrazborс аргументамиx,nilи1. В результате выполнения кода будет выведено сообщение об ошибке, так как условие(null x)не выполняется.