Programación Funcional con Scheme parte I

Si bien en mi caso, la facultad es la parte aburrida e insulsa de la informática, me ha tocado una materia en la cual intentan hacernos ver diferentes paradigmas de programación. Por lo que debo destacar, que por esta vez, me divertí aprendiendo. A continuación, algunas funciones, desarrolladas bajo el paradigma funcional puro con el lenguaje SCHEME ;)


;;----------------------------------------------------------------------------;;
;; Ejercicio 1 ;;
;; Contrato: cuenta la cantidad de apariciones de un
;; elemento en una lista. El primer parámetro es el
;; elemento a buscar y el segundo la lista en la que
;; se deber buscar.
;;----------------------------------------------------------------------------;;

(define count-elem(lambda (num lista)
(if (null? lista)
0
(if (= (car lista) num)
(+ (count-elem num (cdr lista)) 1)
(count-elem num (cdr lista))
);if
);if
);lambda
);define

(count-elem 3 '(1 3 4 3)) ;=> 2


;;-------------------------------------------------------;;
;; Ejercicio 2
;; Contrato: calcula el factorial del valor
;; pasado en n.
;;-------------------------------------------------------;;

(define factorial (lambda (x)
(if (= x 0)
1
(* x (factorial(- x 1)))
);if
)
)

(factorial 0) ;=> 1
(factorial 1) ;=> 1
(factorial 2) ;=> 2


;;--------------------------------------------;;
;; Ejercicio 3
;; Contrato: devuelve el length
;; de una lista.
;;--------------------------------------------;;

(define largo_lista(lambda (lista)
(if (null? lista)
0
(+ (largo_lista (cdr lista)) 1)
);if
);lambda
);define

(largo_lista (list '1 '23 '31 '4 '() '7)); => 6 Probado en lista impropia.
(largo_lista (list '1 '23 '31)) ; => 3 Probado en lista propia.


;;---------------------------------------------------------------------------;;
;; Ejercicio 4 ;
;; Contrato: dados dos parametros en formato hora,
;; a traves de una lista (hh mm ss).
;; Devuelve la suma de las mismas.
;;---------------------------------------------------------------------------;;

(define suma-horas (lambda (hora1 hora2)
(let (
(mtotal (+ (cadr hora1) (cadr hora2)))
(stotal (+ (caddr hora1) (caddr hora2)))
(htotal (+ (car hora1) (car hora2)))
)
(if (> (+ stotal) 59)
(if (> (+ mtotal 1) 59)
(cons (+ htotal 1) (cons (modulo (+ mtotal 1) 60) (cons (modulo (+ stotal) 60) '())))
(cons (+ htotal) (cons (modulo (+ mtotal 1) 60) (cons (modulo (+ stotal) 60) '())))
);if
:
(if (> (+ mtotal 1) 59)
(cons (+ htotal 1) (cons (modulo (+ mtotal) 60) (cons (modulo (+ stotal) 60) '())))
(cons (+ htotal) (cons (modulo (+ mtotal) 60) (cons (modulo (+ stotal) 60) '())))
);if
);if
);let
);lambda
);define


(define devolver_listado (lambda (lista h_salida)
(if (null? lista)
'()
(cons
(list (caar lista) (suma-horas (cdr (car lista)) h_salida))
(devolver_listado (cdr lista) (suma-horas (cdr (car lista)) h_salida))
);cons
);if
);lambda
);define


(define listado (list
(cons "Federico Lacroze" '(00 00 00))
(cons "Jose Artigas" '(00 03 00))
(cons "Pn Parata" '(00 02 00))
(cons "Dr Fco Beiro" '(00 02 00))
(cons "El libertador" '(00 02 00))
(cons "Antonio Devoto" '(00 02 00))
(cons "Cnelfo Lynch" '(00 02 00))
) ;solo por una cuestión de comodidad no incorporé la lista completa.
)
(devolver_listado listado '(05 30 00))


;;--------------------------------------------------------------------------;;
;; Ejercicio 5
;; Contrato: dadas dos listas, concatenarlas en una
;; única lista resultante.
;;--------------------------------------------------------------------------;;

(define concatenar_listas (lambda (lista1 lista2)
(if (and (null? lista1) (null? lista2))
'()
(if (not (null? lista1))
(cons (car lista1) (concatenar_listas (cdr lista1) lista2))
(if (not (null? lista2))
(cons (car lista2) (concatenar_listas lista1 (cdr lista2)))
'()
);if
);if
);if
);lambda
);define

(concatenar_listas (list '1 '2 '3 '()) (list '4 '5 '()));=> (1 2 3 () 4 5 ()) Probado con listas impropias.
(concatenar_listas (list '1 '2 '3) (list '4 '5));=> (1 2 3 4 5) Probado con listas propias.
(concatenar_listas (list '()) (list '()));=> (() ()) Probado con listas vacías


;;---------------------------------------------------------------------------;;
;; Ejercicio 6 ;; Contrato: devuelve el primer elemento
;; de una lista que es un número, si lo
;; encuentra. Caso contrario, devuelve null.
;;---------------------------------------------------------------------------;;

(define devolver_numero (lambda (lista)
(if (null? lista)
"null"
(if (number? (car lista))
:
(car lista)
(devolver_numero (cdr lista))
);if
);if
);lambda
);define

(devolver_numero (list 'a 'b #f '() 'a 89)) ;=> 89


;;------------- -------------------------------------------------------------;;
;; Ejercicio 7
;; Contrato: recibe como parametro un valor y una
;; lista y retorna la lista con los mismos valores
;; excepto el que se pasó por parámetro que se
;; agregará al final.
;;---------------------------------------------------------------------------;;

(define attach-at-end (lambda (numero lista)
(if (null? lista)
numero
(if (= (car lista) numero)
(attach-at-end numero (cdr lista))
(cons (car lista) (attach-at-end numero (cdr lista)))
);if
);if
);lambda
);define

(attach-at-end '2 (list '1 '2 '3 '2 '2 '4 '2 '5));=> (1 3 4 5 2)


;;---------------------------------------------------------------------------;;
;; Ejercicio 8
;; Contrato: recibe 3 parámetros (dos valores y una
;; lista) y devuelve la lista con todos los componentes
;; que son iguales al primer parametro reemplazados
;; por el valor del tercer parámetro.
;;---------------------------------------------------------------------------;;

(define subst(lambda (c k lista)
(if (null? lista)
lista
(if (eqv? c (car lista))
(cons k (subst c k (cdr lista)))
(cons (car lista) (subst c k (cdr lista)))
);if
);if
);lambda
);define

(subst 'c 'k '( c o c o n u t '()))
(subst 'c 'k '( c o c o n u t ))


;;---------------------------------------------------------------------------;;
;; Ejercicio 9
;; Contrato: devolver de la suma del rango de valor
;; que va desde menor hasta mayor.
;;---------------------------------------------------------------------------;;

(define range-sum (lambda (menor mayor)
(if (> menor mayor)
(display "Los parámteros no son correctos")
(if (= menor mayor)
menor
(+ menor (range-sum (+ menor 1) mayor))
);if
);if
);lambda
);define

(range-sum 1 13)
(range-sum 2 2)


;;--------------------------------------------------------------------------;;
;; Ejercicio 10
;; Contrato: recibe como parametros los puntos de
;; dos rectas y determine el punto de intersección
;; de las mismas. Ecuación de la recta que pasa
;; por dos puntos:
;; (y – y1) / (y2 – y1) = (x – x1) / (x2 - x1)
;;--------------------------------------------------------------------------;;

(define interseccion (lambda (x11 y11 x12 y12 x21 y21 x22 y22)
(let* (
(pendiente1 (/ (- y12 y11) (- x12 x11)))
(pendiente2 (/ (- y22 y21) (- x22 x21)))
(ordenada1 (- y11 (* pendiente1 x11)))
(ordenada2 (- y21 (* pendiente2 x21)))
(x-interseccion (/ (- ordenada2 ordenada1) (- pendiente1 pendiente2)))
(y-interseccion (+ (* pendiente1 x-interseccion) ordenada1))
)
(cons x-interseccion y-interseccion)
);let*
);lambda
);define

(interseccion 0.5 0.5 1 1 1 1 3 3)
(range-sum 13 1)

1 comentario:

Sebastian dijo...

hola, me parecen excelentes estos codigos, muy claros, muy sencillos. Tengo un problema con un programa que reciba una lista y devuelva otra lista con todas las sublistas:
> `(a b c d e)
((a b c d)(b c d)(c d)(d))