REPEAT
- Evalúa cada expresión el número de veces que se
especifique en el argumento entero, y devuelve el valor de la
última expresión
-
(repeat entero expresión ... )
- El argumento entero debe ser un número entero
positivo.
Ejemplos de iteraciones con REPEAT:
FACTORIAL ITERATIVO
- Como primer ejemplo analizaremos la función FACT2 propuesta por
Dennis Shinn <jeeper@halcyon.com>
en el newsgroup comp.cad.autocad en septiembre de 1996. La
explicación es nuestra traducción libre del original.
-
(defun fact2 (n / x y)
(setq x 1 y 1)
(repeat (1- n)
(setq x (1+ x) y (* x y) )
)
)
En la primera línea se asigna el valor inicial correcto a las dos
variable que llamamos x e y.
La repetición se establece para un número específico de
veces según el número que se pase como argumento a la
función. Puesto que la operación del cálculo del factorial
implica la cantidad de números a multiplicar menos 1, establecemos en
(1- n) el número de repeticiones.
Ahora vienen los cálculos matemáticos: (setq x (1+ x) y (* x
y))
Durante cada iteración de esta expresión, la x se
incrementa por un valor de 1 cada vez, e y se incrementa como
el producto de ella misma y el próximo valor mayor de x, etc.,
etc.
Obsérvese que no se ha implementado un control de errores, que
es algo deseable en un lenguaje de programación. Tanto 0 como
1 quedan indefinidos, ya que ninguno de los dos permitirá que
ocurra la iteración. El REPEAT simplemente no repite. Vale, sin
embargo para demostrar las posibilidades de un verdadero lenguaje de
programación (como LISP) para realizar verdaderas operaciones de
recursión e iteración.
Como muestra de una implementación para atrapar posibles errores
podríamos crear otra rutina fact3 que llame a la rutina fact2
sólo en los casos apropiados:
(defun fact3 (n)
(cond
((and (numberp n)(> n 1))
(fact2 n)
)
((= n 1) 1)
(t nil)
)
)
En este caso se prueba primero si el argumento n es un número mayor que
1, en cuyo caso se ejecuta la función fact2. En caso de ser igual a 1 se
devuelve 1, y en cualquier otro caso se devolverá NIL.
Predicado PALINDROMOP
- El predicado PALINDROMOP debe devolver T (cierto) si una
cadena de texto es un palíndromo, es decir, si se lee lo mismo de
izquierda a derecha que al revés. Se ha utilizado la función
STRLEN para determinar el número de repeticiones, la
función SUBSTR para ir extrayendo caracteres para compararlos,
uno a uno, comenzando de izquierda a derecha y de derecha a izquierda, y la
función STRCASE de manera que se ignore la caja
(mayúsculas o minúsculas). Se emplean dos variables locales,
cont y resultado. Esta segunda se establece inicialmente como
T y bastará que no sea igual una de las parejas de letras
analizadas para que adopte el valor de NIL (falso). Es obvio que bastará con un número de
repeticiones igual a la mitad de la longitud de la cadena de texto, pues más
allá de eso se estaría comparando las mismas parejas de caracteres. Al ser
ambos argumentos de la división números enteros, el resultado también lo
sería, truncando los decimales, por lo que en una cadena con número impar de
caracteres no se compararía el carácter centras consigo mismo.
-
(defun palindromop (cadena / cont resultado)
(setq
cont 0
resultado t
) ;_ fin de setq
(repeat (/ (strlen cadena) 2)
(if (not
(equal
(strcase (substr cadena (1+ cont) 1))
(strcase (substr cadena (- (strlen cadena) cont) 1))
) ;_ fin de equal
) ;_ fin de not
(setq resultado nil)
) ;_ fin de if
(setq cont (1+ cont))
) ;_ fin de repeat
resultado
) ;_ fin de defun
|
|