{- Tarea a entregar antes del 19 de setiembre de 2023 a las 23 hs -} {- Funciones lineales -} incluir Predefinido conj SecZnoV = { xs en Z* | xs /=[] } {- Ejercicio 1: Escribir dos funciones: cantPos y cantNeg que, dada una secuencia de enteros, devuelven la cantidad de positivos (o cero) y de negativos que hay en la secuencia respectivamente.-} cantPos :: R* -> N cantPos (xs)=0 si xs==[] o 1 + cantPos(resto(xs)) si primero(xs) >= 0 o cantPos(resto(xs)) cantNeg :: R* -> N cantNeg (xs)=0 si xs==[] o 1 + cantNeg(resto(xs)) si primero(xs) < 0 o cantNeg(resto(xs)) {- COMENTARIO: se pide para secuencia de enteros, el dominio debería ser Z* -} {-Escribir una función posNeg que, dada una secuencia, devuelve un par donde el primer elemento es la cantidad de enteros no negativos (positivos o cero) de la secuencia y el segundo la cantidad de negativos. Ejemplo: posNeg ([1,2,7,0,-1,-3, 0]) (5,2)-} posNeg :: SecZnoV -> (N X N) posNeg (xs)=(cantPos(xs),cantNeg(xs)) {- COMENTARIO: la secuencia podría ser vacia y en ese caso devolver (0,0) -} {- Ejercicio 2: Definir el conjunto de secuencias de enteros no vacías, SecZnoV. Usando la función dada: restoZ, escribir una función minSec que, dada una secuencia no vacia de enteros, devuelva el mínimo. Idem para el máximo (maxSec). Ejemplos: minSec([1,3,0,4]) 0 maxSec([1,3,0,4]) 4 maxSec([]) Error: {IntÉrprete columna: 8} Valor [] no pertenece al conjunto SecZnoV porque no se cumple: [[] /= []]. -} restoZ :: Z* -> Z* restoZ (xs) = resto(xs) minSec :: R* -> R minSec (xs)=primero(xs) si restoZ(xs)==[] o primero(xs) si primero(xs) <= minSec(restoZ(xs)) o minSec(restoZ(xs)) maxSec :: R* -> R maxSec (xs)=primero(xs) si restoZ(xs)==[] o primero(xs) si primero(xs) >= maxSec(restoZ(xs)) o maxSec(restoZ(xs)) {- COMENTARIO: es poco eficiente invocar dos veces minSec, tanto en o primero(xs) si primero(xs) <= minSec(restoZ(xs)) y, si es falso, luego en o minSec(restoZ(xs)). Una forma de solucionarlo es utilizar la función predefinida min, y sustituyendo lo anterior por min(primero(xs), minSec(restoZ(xs))) -} {- Ejercicio 3: dado un elemento entero y una secuencia de enteros, escribir una función pertenece, que devuelve True si el elemento está en la lista y False si no. Ejemplos: pertenece (0, [1,3,0,4]) True pertenece (-5, [1,3,0,4]) False -} prtenEntero :: Z X Z* -> Bool prtenEntero (n, xs)= False si xs==[] o True si n==(primero(xs)) o prtenEntero (n,resto(xs)) {- Ejercicio 4: dadas dos secuencias de enteros, escribir una función inter, que devuelve una secuencia con los elementos comunes a ambas. Ejemplo: inter ([1,3,0,4], [-5,3,0,-1,2]) [3,0] -} inter :: Z* X Z* -> Z* inter (zs, xs)= [] si zs==[] o primero(zs): inter(restoZ(zs),xs) si prtenEntero(primero(zs),xs)==True o inter(restoZ(zs),xs) {- COMENTARIO: Funciona bien, pero no es conmutativa: >inter([1,2,2],[1,2]) [1,2,2] >inter([1,2],[1,2,2]) [1,2] -} {- Ejercicio 5: Definir una función mcd que, dados dos naturales a y b distintos de 0, implemente el algoritmo de Euclides para hallar el máximo comun divisor de a y b. Componiendo la función divisores del Predefinido y algunas de las funciones anteriores, definir una función mcdDef que dados dos naturales distintos de 0, devuelva el máximo comun divisor de ellos. -} {- mcdEuc :: Zno0 X Zno0 -> R mcdEuc (a,b)= a si b==0 o b si a==0 o mcdEuc(b,a-b) si a>b o mcdEuc(a,b-a) si b>=a -} mcd :: Nno0 X Nno0 -> N mcd(x,y) = y si mod(x,y) == 0 o mcd(y,mod(x,y)) {- COMENTARIO: falto la composicion de funciones anteriores -}