Форум программистов, компьютерный форум, киберфорум
Lisp
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.65/40: Рейтинг темы: голосов - 40, средняя оценка - 4.65
 Аватар для Alex_DeaD
6 / 6 / 6
Регистрация: 09.12.2013
Сообщений: 104

Программа на Clisp

30.10.2016, 11:14. Показов 8393. Ответов 26
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, подскажите пожалуйста как написать данный вариант программы. Преподаватель вместе с нами учится этому языку и не может ничем помочь, задания он берет с openedu. Пишем мы на clisp. Вот самое задание:

Кликните здесь для просмотра всего текста


Прочитать трехмерный массив из стандартного потока ввода. Массив может содержать элементы различных типов – целые, вещественные, комплексные числа, строки, символы, списки, другие массивы. Необходимо найти сумму целых чисел, не делящихся нацело на 5. Если целых чисел в массиве нет, результат – 0.

Пример:

Дан трехмерный массив

#3A(((1.8 5 #\B "may") ("the" 2.25 1.3 4) (17 0 "force" 55)) (("be" #C(0 1) 5.02 99) ("with" 1.1 (#\Y #\N) 0.87) ("you!" #C(2.2 3.3) 42 4.2)))

Прочитать его из стандартного потока ввода можно с помощью следующей инструкции:

(defparameter arr (read))

Это массив размерности 2x3x4 (вспомните, как узнать размерность массива во время выполнения программы?). В нем содержатся различные элементы, в том числе следующие целые числа:

5 4 17 0 55 99 42

Среди этих чисел есть те, которые не делятся нацело на 5:

4 17 99 42

Их сумма равна 162, этот результат и нужно вывести в стандартный поток вывода.


а вот что я начал писать:
Lisp
1
2
3
(defvar arr (make-array '(2 3 4) :initial-element 0))
(defparameter arr (read))
(print (arr))
строку входящую я писал так как в примере т.е. (((1.8 5 #\B "may") ("the" 2.25 1.3 4) (17 0 "force" 55)) (("be" #C(0 1) 5.02 99) ("with" 1.1 (#\Y #\N) 0.87) ("you!" #C(2.2 3.3) 42 4.2)))

В своём коде я пытался создать в переменную arr массив, потом считать его туда, ну и в конце просто вывести. На что мне интерпретатор пишет: "The function COMMON-LISP-USER::ARR is undefined." Я даже понять не могу.

Спасибо всем заранее, что сюда заглянули. На вас последняя надежда.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.10.2016, 11:14
Ответы с готовыми решениями:

Функции в CLISP
как работает функция subseq? какие параметры у этой функции?

CLISP vs SBCL
Озадачили написать доклад на пару листов. Кто-нибудь из профи может помочь привести пару примеров с простыми задачами, в которых видно, как...

запуск clisp
здравствуйте! я новичок в лиспе, пытаюсь изучить его самостоятельно. не могу запустить слисп. написала в блокноте код программы,...

26
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
28.03.2021, 14:16
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Catstail Посмотреть сообщение
а еще лучше вот этоon't Loop, Iterate!
Не, для условного школьника я бы не стал. На уровне циклов а-ля паскаль преимуществ практически нет, а внешняя зависимость добавляется.

К циклам а-ля паскаль я добавил repeat, потому что он есть в учебниках Кушниренко. Правда, в качестве последовательностей я бы всё-таки взял списки, а не массивы, потому что знать в лиспе массивы и не знать списки - совсем уж дико. А для прохода списка нужен свой цикл, по номеру - нехорошо. Тогда уж и across для строк.

Не по теме:


Есть тут ИРЛ одно дитя, которое время от времени желает программировать. В принципе, решение на CL задач про робота из Кушниренко неплохо идёт. Интерактивность очень кстати.

3
2 / 2 / 0
Регистрация: 27.03.2021
Сообщений: 5
28.03.2021, 19:44
Добрый вечер!
Цитата Сообщение от helter Посмотреть сообщение
(defparameter arr (read))
Это нехорошо, см. выше мою простыню пятилетней давности.
Да,я понимаю и читала, однако в сложившихся обстоятельствах, и режиме жесткого дедлайна вынуждена была описать так, как говорится в лекциях (в том числе в теле самого задания).

Цитата Сообщение от helter Посмотреть сообщение
Смотрите, насколько лучше с отступами. Без отступов невозможно понять, что это вложенные циклы.
За это отдельное спасибо.

Цитата Сообщение от helter Посмотреть сообщение
В этом: (array-dimension (make-array (array-dimensions arr)) 0) чувствуется метод тыка.
Метод тыка чувствуется, потому что, грубо говоря, это он и есть.

Цитата Сообщение от helter Посмотреть сообщение
Вы хотите, чтобы i принимала значения от 0 до (array-dimension arr) минус один. Почему тогда так и не написать? (array-dimension (array-dimensions arr 0)). Вопрос на понимание: что делает ваше выражение?
Так как массив многомерный, а мне надо получить 3 индекса по одному из каждого измерения. Я создаю массив из array-dimensions (получаю, например, 2 3 4) и через array-dimension получаю доступ к определенному параметру массива к 2 в первом цикле, к 3 во втором, к 4 в третьем и прогоняю переменные через все измерения массива и получаю 3 параметра к каждому значению массива для aref. Может я что-то не так поняла, и можно было по другому, такое вполне может быть.

Цитата Сообщение от helter Посмотреть сообщение
(setf e (incf (cdr e)))
Здесь setf не выполняет никакой функции. Этот оператор изменяет значение переменной ― в данном случае, переменной по имени E. Вы говорите: я хочу, чтобы буквой e теперь обозначалось значение, которое вернуло выражение (incf (cdr e)). Вопрос на понимание: а какое значение оно вернуло?
Если честно, то не очень понимаю, эта часть кода из лекции. На нативном уровне оно плюсует единицу во вторую конс-ячейку повторяющегося в массиве arr значения, которое ранее было записано как ключ в первой конс-ячейке одного из значений alist.

Цитата Сообщение от helter Посмотреть сообщение
Первую часть решения можно записать в виде функции:

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
(defun frequencies (arr)
  (let ((alist '()))
    (dotimes (i (array-dimension arr 0))
      (dotimes (j (array-dimension arr 1))
        (dotimes (k (array-dimension arr 2))
          (let ((e (assoc (aref arr i j k) alist)))
            (if e
                ;нашли - увеличиваем счетчик
                (incf (cdr e))
                ;не нашли - добавляем пару со значением счетчика
                (push (cons (aref arr i j k) 1) alist))))))
    alist))
По массиву она составляет список частот.
Спасибо, я обязательно это испробую ваши подсказки в дальнейшем. Но, так как дедлайны горели, а обучение продолжать надо не смотря ни на что, я использовала то, что поняла и сделала так, как умею.
В итоге, на задание:
Прочитать трехмерный массив, содержащий строки, из стандартного потока ввода. Необходимо определить, какая строка встречается в массиве чаще всего, и вывести на экран количество вхождений.

Пример:
Дан трехмерный массив
#3A((("R" "Lisp" "Python" "perl") ("C" "Lisp" "Pascal" "D")) (("SQL" "Java" "Pascal" "Lisp") ("Nemerle" "R" "Julia" "piet")) (("C++" "Oberon" "C" "Pascal") ("Lisp" "Python" "Ruby" "FORTRAN")))
Прочитать его из стандартного потока ввода можно с помощью следующей инструкции:
(defparameter arr (read))
Это массив размерности 3x2x4 (вспомните, как узнать размерность массива во время выполнения программы?). Чаще всего в нем встречается строка "Lisp" – количество вхождений этой строки равно 4, этот результат и нужно вывести в стандартный поток вывода.

Подсказка: для того, чтобы определить, сколько раз в массиве встречается каждый элемент, можно использовать ассоциативные списки.
Мой код выглядит следующим образом:
Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(defparameter arr (read))
(defparameter alist nil)(dotimes (i (array-dimension (make-array (array-dimensions arr)) 0))
    (dotimes (j (array-dimension (make-array (array-dimensions arr)) 1))
        (dotimes (k (array-dimension (make-array (array-dimensions arr)) 2))
            (let ((e (assoc (aref arr i j k) alist
                    :test #'string=)))
                (if e
                ;нашли - увеличиваем счетчик
                (setf e (incf (cdr e)))
                ;не нашли - добавляем пару со значением счетчика
                (push (cons (aref arr i j k) 1) alist))))))(defparameter list_max nil)(dotimes (z (+ 1 (array-total-size arr))) ;счетчик по количесту элементов в массиве
    (pushnew (cdr (rassoc z alist)) list_max))  ;поиск совпадений (количесто повторений)(print (car list_max))
Ваш совет, к сожалению, я использовать не успела, так как скорость моего кодинга оставляет желать лучшего. Да и понимаю я все это "со-скрипом".

Цитата Сообщение от helter Посмотреть сообщение
Если бы я учил человека программированию, используя CL (например, в духе учебников информатики Кушниренко), я бы не вводил циклы dotimes и пр. Я бы ограничился, например, следующими вариантами loop, которые предложил бы воспринимать как независимые операторы.
Я не устаю вас благодарить, за ценные советы. Запишу учебник Кушниренко в todo-list. А ваши варианты разберу и буду использоваь и использовать в дальнейшем.
0
 Аватар для _sg
4710 / 4405 / 380
Регистрация: 12.05.2012
Сообщений: 3,102
28.03.2021, 21:22
Lisp
1
2
3
4
5
6
7
8
9
(defun max-frequent
    (arr &aux (ar (make-array
                   (apply #'* (array-dimensions arr))
                   :displaced-to arr)))
  (loop for a across (remove-duplicates ar)
        maximize (count a ar :test #'string-equal)))
 
> (max-frequent #3A((("R" "Lisp" "Python" "perl") ("C" "Lisp" "Pascal" "D")) (("SQL" "Java" "Pascal" "Lisp") ("Nemerle" "R" "Julia" "piet")) (("C++" "Oberon" "C" "Pascal") ("Lisp" "Python" "Ruby" "FORTRAN"))))
4
Добавлено через 1 минуту
Lisp
1
2
3
4
5
> (print (max-frequent (read)))
#3A((("R" "Lisp" "Python" "perl") ("C" "Lisp" "Pascal" "D")) (("SQL" "Java" "Pascal" "Lisp") ("Nemerle" "R" "Julia" "piet")) (("C++" "Oberon" "C" "Pascal") ("Lisp" "Python" "Ruby" "FORTRAN")))
 
4 
4
0
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
28.03.2021, 21:24
Ну. Например, у вас массив 2х3х4, и вас интересует, как получить эти размерности ― 2, 3, 4. Здесь есть два способа. Если нужны все сразу, то можно воспользоваться функцией array-dimensions, которая вернёт список из этих размерностей: (2 3 4). Если же требуется узнать одну размерность ― вдоль конкретной оси ― то можно воспользоваться функцией array-dimension, которая принимает массив и номер оси. Например, (array-dimension arr 0) в данном случае дало бы 2, а (array-dimension arr 1) дало бы 3. (Нумерация всего, связанного с массивами, в CL начинается с нуля.)

А что делаете вы? make-array создаёт массив указанной размерности. Вы вычисляете полную размерность массива arr, создаёте новый массив такой же размерности и вычисляете размерность этого массива вдоль оси с помощью array-dimension. Конечно, промежуточный массив не нужен. Если вам нужна размерность оси номер 0 массива arr, вы можете узнать её непосредственно как (array-dimension arr 0).

Цитата Сообщение от Owl_L Посмотреть сообщение
Если честно, то не очень понимаю, эта часть кода из лекции. На нативном уровне оно плюсует единицу во вторую конс-ячейку повторяющегося в массиве arr значения, которое ранее было записано как ключ в первой конс-ячейке одного из значений alist.
Да. Это делает incf. Три вещи: 1) вычисляет новое значение 2) куда-то записывает его (в данном случае ― в cdr, и это немного магия) 3) возвращает его. (Это особенность лиспа ― всякое выражение возвращает значение, даже если мы вычисляли его и не для получения значения.) А setf что делает? Он присваивает возвращённое incf-ом значение (значение частоты ― число!) переменной e, которая, к счастью, дальше не используется.

Цитата Сообщение от Owl_L Посмотреть сообщение
Запишу учебник Кушниренко в todo-list.
Ну, это смотрите. Это школьные учебники, в которых используется КуМир ― не знаю, насколько вам это интересно. У Кушниренко ещё есть более серьёзный учебник «Программирование для математиков», который, надо полагать, может быть полезен не только математикам. Там в основном псевдокод.

Не знаю, конечно, что у вас за курс, и из каких соображений в качестве первого языка выбран CL. Но советую обязательно работать интерактивно, если вы вдруг так не делаете. Для обучения эта особенность лиспа ― интерактивная разработка ― очень кстати.
1
 Аватар для zeroalef
200 / 236 / 33
Регистрация: 29.03.2019
Сообщений: 667
29.03.2021, 01:55
Цитата Сообщение от helter Посмотреть сообщение
У Кушниренко ещё есть более серьёзный учебник «Программирование для математиков», который, надо полагать, может быть полезен не только математикам.
Качнул на посмотреть. Оказалось, любопытненькая веСЧь. Но! Положим рядом трёхтомник Кнута, и окажется что там охват материала гораздо ширее (или ширше, я не знаю).
0
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
29.03.2021, 02:49
Я думаю, Кушниренко не претендовал на лавры Кнута. Это просто учебник для достаточно юных студентов. Довольно ограниченного охвата - основы императивного программирования. Так что он не заменяет собой SICP и другие хорошие книги. А практические задачки там очень неплохие рассматриваются. И, кроме того, написано человеком умным и квалифицированным.

А Кнута я, честно говоря, не читал и не думаю, что когда-нибудь буду читать.
0
 Аватар для zeroalef
200 / 236 / 33
Регистрация: 29.03.2019
Сообщений: 667
29.03.2021, 11:26
helter, вам уже и не нужно, студентам же.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.03.2021, 11:26

функционалы CLisp
Пишу на Command Lisp, проблема в следующем коде, который не работает и я не могу понять почему. Имеется две функции: (defun pf (x f)...

Несложные задания на clisp
Помогите, пожалуйста, выполнить задачки! Заранее благодарю =) 1. Определить функцию сравнения двух списков содержащих не более 3-х...

Clisp работа с классами
Здравствуйте1 Задача: В кадровой службе предприятия собраны сведения о работниках предприятия: табельный но-мер, фамилия, дата рождения,...

Простая рекурсия CLISP
Здравствуйте, помогите пожалуйста составить функцию separate для преобразования списка вида (1 2 3 4) до ((((1)2)3)4). И вторую функцию...

Работа со списками, clisp
clisp есть список > '(((1 2 3 4) 5 6 7 8) 9) (((1 2 3 4) 5 6 7 8) 9) (setq a '(((1 2 3 4) 5 6 7 8) 9)) (((1 2 3 4) 5 6 7 8)...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
27
Ответ Создать тему
Новые блоги и статьи
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru