0 / 0 / 0
Регистрация: 29.10.2012
Сообщений: 5
1

Создает на n - уровне вложенный список, элементом которого на самом нижнем уровне является n

01.04.2013, 08:22. Показов 1786. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Я решил задачу так:
Lisp
1
2
3
4
5
6
7
8
9
10
CL-USER 1 >  (defun f (l n)
(cond 
     (( eq n 0) l)
     ((null l) (f (list n) (- n 1))) 
     (t (f (cons l (list n)) (- n 1))))
)
F
 
CL-USER 2 > (f '() 4)
((((4) 3) 2) 1)
Мне преподаватель сказал чтобы не передавал пустой список параметром, передавать нужно только n. Помогите исправить я немогу решить данную задачу не передавая пустой список.

Добавлено через 3 минуты
Задачу решил сам через опциональную переменную:
Lisp
1
2
3
4
5
6
7
8
9
10
(defun f ( n &optional l)
(cond 
(( eq n 0) l)
((null l) (f (- n 1) (list n))) 
(t (f (- n 1) (list l))))
)
F
 
CL-USER 4 > (f 3)
(((3)))
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.04.2013, 08:22
Ответы с готовыми решениями:

Сформировать N-уровневый вложенный список, элементом которого на самом глубоком уровне является число N
Мужики помогите, задание программы- Формировать N-уровневый вложенный список, элементом которого на...

Найти файлы на самом нижнем уровне
В программе пользователь выбирает папку, в которой находится что-то такое Как мне сделать, чтобы...

Поиск наибольшего на нижнем уровне мультисписка
Здравствуйте! Интересует вопрос: есть мультисписок, на верхнем уровне которого находится Страна, а...

Выровнять текст по вертикали на одном уровне с элементом
Подскажите, пожалуйста, как "приподнять" текст, чтобы он был по центру блока #reserve Скриншот...

13
4699 / 4394 / 380
Регистрация: 12.05.2012
Сообщений: 3,096
01.04.2013, 08:36 2
как вариант:
Lisp
1
2
3
4
5
(defun onion-n (n &optional (m n))
  (if (zerop n) m (list (onion-n (1- n) m))))
 
> (onion-n 7)
(((((((7)))))))
1
Модератор
Эксперт функциональных языков программированияЭксперт Python
36601 / 20330 / 4220
Регистрация: 12.02.2012
Сообщений: 33,643
Записей в блоге: 13
01.04.2013, 10:49 3
А если хочется, чтобы одна функция и с одним параметром, то можно так:

Lisp
1
2
3
4
5
6
7
8
9
(defun onion (n)
  (labels ((oo (k &optional (p k))
            (if (zerop p) k (list (oo k (1- p)))))) (oo n)))
 
==> onion
 
(onion 5)
 
==> (((((5)))))
Добавлено через 3 минуты
или так:

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
(defun onion (n)
 (let ((res (list n)))
  (dotimes (i (1- n) res)
    (push (list (pop res)) res))))
 
==> onion
 
(onion 3)
 
==> (((3)))
 
(onion 7)
 
==> (((((((7)))))))
1
1050 / 944 / 107
Регистрация: 04.11.2012
Сообщений: 974
Записей в блоге: 3
01.04.2013, 10:57 4
Для поддержания разговора.
Lisp
1
2
3
4
5
(defun onions (a)
  (do ((c a (1- c))
       (acc a))
       ((= c 0) acc)
       (setf acc (list acc))))
1
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
01.04.2013, 11:11 5
ncuxonaT, у вас совершенно правильное рекурсивное решение. Конечное, &optional аргумент - это костыль. Вам нужна переменная-аккумулятор, чтобы складывать в неё вычисленное значение и передавать следующему вызову функции. В таких случаях стандартно используется вспомогательная функция:
Lisp
1
2
3
4
5
6
(defun f (n)
  (labels ((ff (n l)
             (cond ((eq n 0) l)
                   ((null l) (ff (- n 1) (list n)))
                   (t (ff (- n 1) (list l))))))
    (ff n '())))
Здесь ff - вспомогательная функция, которая принимает счётчик n и список-аккумулятор l, её код - это ваш код. А чтобы получить ответ, применяем эту функцию к значению счётчика n и пустому аккумулятору. labels - аналог let для создания локальных функций.

ncuxonaT, функции неудобно определять в REPLе, ведь нет естественного способа сохранять их оттуда. Обычно открыт рабочий файл и REPL. Функцию пишут в файле, загружают в REPL (evaluate definition, для него должно быть сочетание) и там тестируют.

Ну и код ваш без отступов нечитаем, а висячие на отдельных строках скобки просто ужасны.
0
Модератор
Эксперт функциональных языков программированияЭксперт Python
36601 / 20330 / 4220
Регистрация: 12.02.2012
Сообщений: 33,643
Записей в блоге: 13
01.04.2013, 11:18 6
Цитата Сообщение от helter Посмотреть сообщение
Конечное, &optional аргумент - это костыль.
- что такое "костыль"?
0
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
01.04.2013, 11:53 7
Не слишком элегантное адхоковое решение, "лишь бы работало". Ведь опциональных параметров "не заказывали".
0
Модератор
Эксперт функциональных языков программированияЭксперт Python
36601 / 20330 / 4220
Регистрация: 12.02.2012
Сообщений: 33,643
Записей в блоге: 13
01.04.2013, 12:05 8
Не хочу показаться навязчивым, но:

1) не понимаю, почему "не слишком элегантное". Длинное? Нет... С labels длиннее.
2) что значит "не заказывали"? На то они и опциональные, что их при вызове можно не задавать...
3) Зачем их (&optional) тогда вообще реализовали в Лиспе, если они (&optional) порождают неэлегантные решения?
0
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
01.04.2013, 12:46 9
Не-ет. Если бы я хотел сказать "короче", я бы и написал "короче". И если опциональные не нужны здесь, это не значит, что они не нужны нигде. Другими словами, сама по себе синтаксическая конструкция не порождает с необходимостью неэлегантные решения - даже безусловный переход бывает оправданным.

Здесь у нас совершенно стандартная для функционального программирования ситуация, когда требуется рассмотреть более общую функцию, принимающую дополнительные аргументы-аккумуляторы. И эта задача хрестоматийно решается стандартным приёмом. В качестве примера тем, кто не видел, показываю хвосторекурсивный факториал:
Lisp
1
2
3
4
5
6
(defun factorial (n)
  (labels ((fac (n acc)
             (if (zerop n)
                 acc
                 (fac (- n 1) (* n acc)))))
    (fac n 1)))
Здесь рекурсия имитирует цикл. Вместо итераций мы повторно вызываем функцию, а счётчик и параметр передаются ей как аргументы. Пример работы:
factorial(5) = fac(5, 1) = fac(4, 5) = fac(3, 20) = fac(2, 60) = fac(1, 120) = fac(0, 120) = 120.

Для реализации этой базовой вещи достаточно базовых средств, и совершенно не имеет значения, есть ли в языке такое роскошество как опциональные аргументы. Зачем изобретать какие-то workaround-ы? Если кажется слишком длинно, можно написать макрос навроде named let и в него обёртывать. Но раз его нет в стандарте, может, не так он и нужен в CL.

Со стороны заказчика тоже подозрительно. Если я хотел обычную функцию одного переменного, а мне подсовывают ещё опциональный аргумент, я буду недоволен. Может, я хотел, чтобы сразу были исключения, когда я по ошибке совал бы два аргумента. Ну а если бы мне не сказали об опциональном (недокументированный аргумент, так сказать), то вердикт один - баг!
2
Модератор
Эксперт функциональных языков программированияЭксперт Python
36601 / 20330 / 4220
Регистрация: 12.02.2012
Сообщений: 33,643
Записей в блоге: 13
01.04.2013, 13:12 10
Цитата Сообщение от helter Посмотреть сообщение
И эта задача хрестоматийно решается стандартным приёмом.
- согласен (и даже написал похожее решение выше). Согласен и с тем, что опциональный аргумент "повышает опасность". Но уродливым (неэлегантным) решение не становится.

Да и чем рискуем, если подставим что-либо на место опционального параметра? Атом, список - да, это вызвет ошибку... Но точно так же можно "завалить" решение, подставив что-либо неудобоваримое на место обязательного параметра.

Подставим на место опционального параметра положительное число m. Функция нормально отработает, только решит другую задачу: построит "луковицу" с другим числом "одежек"

Кстати все приведенные выше программы будут вести себя плохо, если задать отрицательное число "одежек"
0
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
01.04.2013, 13:21 11
Вопрос об элегантности изначально субъективный. Да и тоже от контекста зависит. Хочется, однако, навязать человеку своё видение. Главное, ncuxonaT сам решил задачу и ввёл-таки этот параметр-аккумулятор, что, как мне кажется, самое сложное в концептуальном плане.
0
Модератор
Эксперт функциональных языков программированияЭксперт Python
36601 / 20330 / 4220
Регистрация: 12.02.2012
Сообщений: 33,643
Записей в блоге: 13
01.04.2013, 13:40 12
Цитата Сообщение от helter Посмотреть сообщение
Хочется, однако, навязать человеку своё видение.
- резковато... Я бы сказал "доказать правильность моего мнения". Лично я не люблю, когда мне что-либо навязывают. Вероятно, поэтому и стал программистом.

Добавлено через 28 секунд
Цитата Сообщение от helter Посмотреть сообщение
Вопрос об элегантности изначально субъективный.
- что я и имел в виду...
0
helter
01.04.2013, 13:48
  #13

Не по теме:

Цитата Сообщение от Catstail Посмотреть сообщение
- резковато... Я бы сказал "доказать правильность моего мнения".
Я про себя. Ведь это я начал разговор об элегантности, именно чтобы навязать передать начинающему свои представления о прекрасном. Есть у меня такой отрицательный минус. :)

1
2304 / 1063 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
01.04.2013, 16:35 14
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от helter Посмотреть сообщение
Вопрос об элегантности изначально субъективный.
Не факт. На мой взгляд, код который решает задачу в какой-либо проблемной области и при это оперирует терминами самой области более "элегантный", чем низкоуровневый код, который только "делает вид" что разговаривает терминами области.
Например, сложно назвать код запроса к ЭС элегантным, если он пестрит низкоуровневыми подробностями работы с пямятью и ворочит указателями.

Люблю Lisp за то, что могу построить любую необходимую степень абстракции.
Есть у меня отдел тестировщиков. Они даже не знают, что пишут на моём DSL, который компилируется в Lisp. Они счастливы. И в гробу видели все эти уродские питоновские, рубиновские и js'овские фреймворки для тестирования. Проходили мы уже это. Знаем
2
01.04.2013, 16:35
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.04.2013, 16:35
Помогаю со студенческими работами здесь

Список на уровне с изображением
<br /><img src="путь к картинке" align="left"/> <ul> <li>1</li> <li>2</li> ...

Хочу изучить TCP/IP на самом глубоком уровне. Что "внутри" библиотеки ws2_32.dll (winsock)?
Предисловие (можно не читать если не интересно) Разрабатываю клиент-серверную архитектуру, от...

Сформировать список атомов на указанном уровне
Доброй вечер. Задача такова: В исходном списке нужно сформировать списки атомов на введенном...

Вывести список вершин на заданном уровне дерева
Добрый день! Дано бинарное дерево и номер уровня. Вывести список вершин на данном уровне....


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru