Покритиковать, улучшить, закончить - Lisp

Узнай цену своей работы

Формулировка задачи:

Покритиковать, улучшить, закончить, помочь. Нужно рассказать, что не так в моей программе: где её можно улучшить, где велосипеды или костыли, можно ли сделать быстрее(важно), что подправить и т.д. , помочь её закончить(осталась одна функция). Всем заранее спасибо. Собственно говоря, вот что она делает. Дана квадратная матрица M размера n, элементы которой - целые числа. Дальше R=(m(0), m(1), ..., m(k-1)) массив состоящий из k подматриц матрицы M. 1. Определить количество уникальных сумм подматриц(klasa abstrakcji (не знаю как правильно перевести) из R. 2. Определить количество сумм которые встречались больше всего раз. 3. Найти целую часть среднего арифметического всех сумм. Ввод n k матрица размера n k-количество координат для подматриц (две координаты левого угла, две - правого) Вывод Пункт1 Пункт2 Пункт3 Ограничения n [1 ; 10^4], k [1 ; 10^8], M - целые числа [-10^3,10^3] Лимиты По времени O(n^2+klgk), по памяти O(n^2+k) Пример
;;Ввод
4 8        ;;n k
-2 -2 -3 1     ;;\
3 0 1 3        ;;| сама матрица
1 3 -3 3       ;;|
2 0 0 -2       ;;/
0 0 2 1 ;;\
2 2 2 3 ;;|
1 2 1 3 ;;|Координаты для подматриц
3 2 3 3 ;;|
3 0 3 3 ;;|
0 1 2 1 ;;|
3 3 3 3 ;;|
1 3 1 3 ;;/
;;Вывод:
5 3 0
Вот что написал, проблема с функцией нахождения подматрицы, я не знаю как её сделать.
(defun get-sum (lst)
    "Returns sum of given list"
    (reduce #'+ lst))
 
(defun get-average-entire-part (list-of-subs)
    "Возвращает целую часть среднего арифметического данного листа"
    (truncate 
        (/ (get-sum list-of-subs) (length list-of-subs))))
 
(defun get-unique-sums (lst)
    "Возвращает список элементов без дубликатов и количество этих элементов"
    (let ((tmp (remove-duplicates lst)))
        (values tmp (length tmp))))
 
(defun most-repeats (check-lst lst)
    "Возвращает список элементов, которые повторяются в 
    данном списке(и соответствуют искомым элементам из check-list)
    наибольшее количество раз и количество этих элементов
    Пример:
    (most-repeats '(1 2 3) '(2 2 3 3 4 1 5 5 5 5 5)) -> (2 3) 2"
    (let ((most nil) (cnt 0))
        (dolist (i check-lst)
            (let ((tmp (count i lst)))
                (cond
                    ((= tmp cnt) (push i most))
                    ((> tmp cnt) (setf most (list i) cnt tmp))
                    (t most))))
        (values most cnt)))
 
(defun get-size-coor (line)
    "Возвращает два числа из строки
    (в данном частном случае размер М и количество подматриц)"
    (let (size coor (pos 0))
        (multiple-value-setq (size pos) (parse-integer line :start pos :junk-allowed t))
        (multiple-value-setq (coor pos) (parse-integer line :start pos :junk-allowed t))
        (values size coor)))
 
(defun get-coordinates (line)
    "Возвращает массив с 4 числами из данной строки
    (в данном случае координаты)"
    (let ((coordinates (make-array 4 :element-type 'integer)) (pos 0) tmp)
        (dotimes (i 4)
            (multiple-value-setq (tmp pos) (parse-integer line :start pos :junk-allowed t))
            (setf (aref coordinates i) tmp))
        coordinates))
 
(defun create-fill-matrix (size)
    ;;Странное поведение если запускать из repl!!!
    "Создает квадратную матрицу размера SIZE x SIZE
    и считывает её элементы из standart-input. 
    Ну и заполняет."
    (let ((matrix (make-array (list size size) :element-type 'integer)))
        (dotimes (i size)
            (let ((line (read-line))
                  (pos 0)
                   tmp)
                (dotimes (i2 size)
                    (multiple-value-setq (tmp pos) (parse-integer line :start pos :junk-allowed t))
                    (setf (aref matrix i i2) tmp))))
        matrix))
 
(defun get-submatrix (matrix coordinates)
    ;;Не знаю как сделать
    "Возвращает массив элементов из подматрицы по координатам данным в виде массива
    Пример:
    (get-submatrix #2A((0 1 2) (3 4 5) (6 7 8)) #(0 0 1 2)) -> #(0 1 2 3 4 5)"
    )
(defun main ()
    "Главная функция"
    (let (size coor-num)
        (multiple-value-setq (size coor-num) (get-size-coor (read-line)))
        (let ((matrix (create-fill-matrix size))
              (all-sums nil)
              (unique-sums nil)
              (num-of-unique 0)
              (most nil)
              (num-of-most 0)
              (shit 0))
            (dotimes (i coor-num)
                (push (get-sum (get-submatrix matrix (get-coordinates (read-line)))) all-sums ))
            (multiple-value-setq (unique-sums num-of-unique) (get-unique-sums all-sums))
            (multiple-value-setq (most num-of-most) (most-repeats unique-sums all-sums))
            (setf shit (get-average-entire-part all-sums))
            (format t "~s ~s ~s" num-of-unique num-of-most shit))))
Пример подматрицы по координатам 0 1 2 3 4 5 6 7 8 -> 0 0 1 2

0 1 2 3 4 5

6 7 8 Если что-то непонятно обьяснил, спросите расскажу как смогу

Решение задачи: «Покритиковать, улучшить, закончить»

textual
Листинг программы
(defun get-submatrix-sum (matrix coordinates)
    ;;Не знаю как сделать
    "Возвращает массив элементов из подматрицы по координатам данным в виде массива
    Пример:
    (get-submatrix #2A((0 1 2) (3 4 5) (6 7 8)) #(0 0 1 2)) -> (+ 0 1 2 3 4 5) -> 15"
    (let ((sum 0))
        (loop for i from (aref coordinates 0) to (aref coordinates 2) do
            (loop for j from (aref coordinates 1) to (aref coordinates 3) do
                (incf sum (aref matrix i j))))
        sum))

Оцени полезность:

6   голосов , оценка 3.5 из 5