;; Вспомогательная функция: проверка, является ли элемент числом
(defun numberp-custom (x)
  (and (atom x) (numberp x)))

;; Основная функция: вычисление сумм по уровням
(defun sum-by-levels (lst)
  (let ((result (make-hash-table))) ; Используем hash table для хранения сумм по уровням

    ;; Внутренняя рекурсивная функция
    (labels ((process-level (sub-lst level)
               (cond
                 ((null sub-lst) nil) ; Конец списка

                 ((atom sub-lst)
                  (if (numberp-custom sub-lst)
                      (progn
                        (incf (gethash level result 0) sub-lst) ; Добавляем число к сумме уровня
                        nil) ; Возвращаем nil
                      nil))        ; Игнорируем не числовые атомы

                 (t ; Список
                  (process-level (car sub-lst) (1+ level)) ; Обрабатываем первый элемент (углубляемся)
                  (process-level (cdr sub-lst) level)))) ; Обрабатываем остаток списка
      )
      (process-level lst 1) ; Начинаем обработку с уровня 1

      ;; Преобразуем hash table в список требуемого формата ((level сумма)) и сортируем по уровню
      (sort (loop for level being the hash-keys of result
                  using (hash-value sum)
                  collect (list level sum))
            #'< :key #'car))))

;; Примеры использования:
(print (sum-by-levels '(a (b (4 (2 e (3) k 15) e 5) 7))))
;; → ((1 0) (2 7) (3 9) (4 17) (5 3))

(print (sum-by-levels '(1 (2 (3 (4) 5) 6) 7)))
;; → ((1 1) (2 7) (3 11) (4 4))
