LINUX.ORG.RU

clisp vs loops


0

0

Можно ли (как?) в Common Lisp'e без циклов (dotimes, loop, do и т.д.)
используя, например, семейство map сделать, например, следующее:

1. Заполнить вектор числами от 0 до N #(0 1 2 3 4 ....N), но не при
создании вектора, а позже. Или в диапазоне от M до N.
2. Произвести над каждым элементом вектора какое-либо действие.
(Например, -,+*/-ить каждый элемент на другое число).
3. Применить какую-либо ф-цию к каждому эл-ту (sin, cos и т.д.)

Это примеры так, навскидку. 

anonymous

можно так(хотя и убого выглядит)
(let ((i 0))
(mapcar (lambda (x) (prog1 (+ x i) (incf i))) '(1 2 3)))
или на "чистых" замыканиях(у Олега Киселева можно подсмотреть)
и потом, c помощью mapcar - вы будете реализовать тот же цикл

bik ★★
()

(setq v (make-array 0 :fill-pointer t))

> 1. Заполнить вектор числами от 0 до N #(0 1 2 3 4 ....N), но не при создании вектора, а позже. Или в диапазоне от M до N.

(defun fill-vector (vec start end) (labels ((rec (iter) (cond ((> iter end) vec) (t (vector-push-extend iter vec) (rec (+ iter 1)))))) (rec start)))

(fill-vector v 10 20)

> 2. Произвести над каждым элементом вектора какое-либо действие. (Например, -,+*/-ить каждый элемент на другое число).

> 3. Применить какую-либо ф-цию к каждому эл-ту (sin, cos и т.д.)

(map 'vector #'(lambda (x) (your-[action|function] x)) v)

asgard
()
Ответ на: комментарий от asgard

ужос нафиг, как все таки чище^Wсинтаксически менее перегруженным код выглядит на scheme:

(define (crlst start end) (cond ((<= (- end start) 0) (cons start '())) (else (cons start (crlst (+ start 1) end)))))

UrbanSerj
()
Ответ на: комментарий от UrbanSerj

> ужос нафиг, как все таки чище^Wсинтаксически менее перегруженным код выглядит на scheme:

в принципе, в cl варианте можно обойтись и без labels, и юзать рекурсию напрямую

(defun my-rec-func ....
(my-rec-func ....))

но labels гораздо лучше оптимизируется. quote from "common lisp the language":
---
Lisp compilers can be very smart about calls to `known functions'. If a function is lexically nested within another, via FLET or LABELS, the compiler can often perform extensive optimizations that will reduce or eliminate the function call overhead.
---

+ речь всё таки шла о векторе, а не о списках. а схема, если мне не изменяет, таки имеет vector-type.

asgard
()
Ответ на: комментарий от asgard

>+ речь всё таки шла о векторе, а не о списках. а схема, если мне не изменяет, таки имеет vector-type.

не заметил... list->vector спасет мир

а вообще задания предложенные автором топика, имхо, сильно тривиальны

/me бы предложил реализовать fold-right через fold-left (и наоборот) с использованием хвостовой рекурсии

UrbanSerj
()
Ответ на: комментарий от UrbanSerj

> /me бы предложил реализовать fold-right через fold-left (и наоборот) с использованием хвостовой рекурсии

=)

[offop] если хотите сложности, могу предложить ещё более интересную задачу, которую я недавно закончил решать на cl:

у вас есть шахматная доска NxN, на ней нужно разместить 2*N шашек(по 2 на одной горизонтале) и получить все возможные комбинации расстановок шашек такие, что ни одни 3 шашки не стоят на одной прямой(прямая определяется не в "шахматном понимании", т.е. если через любые 2 данные шашки(точки) можно провести прямую, и эта прямая пройдёт через 3ю шашку(точку), то комбинация считается не верной). при этом можно использовать исключительно функциональный подход. т.е. конечная программа не должна содеражать side-effect'ов.

сразу скажу, что чёткой формулы для итоговой последовательности нет. максимальное N, для которого нашлись такие комбинации = то ли 54, то ли 58.

asgard
()
Ответ на: комментарий от asgard

> (map 'vector #'(lambda (x) (your-[action|function] x)) v)

Вот, например, вычесть из каждого эл-та v 5, таким образом. У меня не получается :)

anonymous
()
Ответ на: комментарий от anonymous

> Вот, например, вычесть из каждого эл-та v 5, таким образом. У меня не получается :)

(setq v (map 'vector #'(lambda (x) (- x 5)) v))

asgard
()

1:
(defun fill-vector (vector)
  (let ((i -1))
    (map 'vector #'(lambda (x) (incf i)) vector)))

stassats ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.