Skip to content

Instantly share code, notes, and snippets.

@vitaminac
Last active November 19, 2019 07:10
Show Gist options
  • Save vitaminac/1f3fe97ce71784ff7366894c8d4d12c2 to your computer and use it in GitHub Desktop.
Save vitaminac/1f3fe97ce71784ff7366894c8d4d12c2 to your computer and use it in GitHub Desktop.
Haskell Ejercicio URJC
module HashkellEj where
import Data.Char
import Data.List
---------------------- TEMA 2 ----------------------
-- Implementar una función en Haskell que dados tres números enteros
-- determine si están ordenados de menor a mayor.
estanOrdenados :: Int -> Int -> Int -> Bool
estanOrdenados x y z = (x < y) && (y < z)
-- Implementar una función en Haskell que dados tres números enteros
-- los devuelva ordenados de menor a mayor
ordenarTresNumeros :: Int -> Int -> Int -> [Int]
ordenarTresNumeros x y z
| ((x <= y) && (y <= z)) = [x, y, z]
| ((x <= z) && (z <= y)) = [x, z, y]
| ((y <= x) && (x <= z)) = [y, x, z]
| ((y <= z) && (z <= x)) = [y, z, x]
| ((z <= x) && (x <= y)) = [z, x, y]
| otherwise = [z, y, x]
-- Implementar en Haskell una función que reciba un número real
-- y devuelva una tupla con su parte entera
-- y sus dos primeros decimales (como número entero).
tuplarDecimal :: Double -> (Int, Int)
tuplarDecimal n = (truncate n, mod (truncate (n * 100)) 100)
-- Crear una función que reciba el radio de una circunferencia
-- y devuelva una 2-tupla con la longitud de la circunferencia
-- y con el área del círculo.
-- Emplea una definición local
-- con la cláusula where para almacenar el valor de Pi
longArea :: Float -> (Float, Float)
longArea r = (2 * p_i * r, p_i * r^2)
where
p_i = 3.1415926
-- A continuación crear una función
-- con el mismo cometido empleando la definición local let
longAreaLet :: Float -> (Float, Float)
longAreaLet r = let p_i = 3.1415926 in (2 * p_i * r, p_i * r^2)
-- Implementar la función predefinida de listas concat,
-- que se llamará concatenar,
-- utilizando la definición de listas por comprensión
concatenar :: [[Int]] -> [Int]
concatenar l = [y |x <- l, y <- x]
-- Implementar una función que dado un número entero
-- devuelva en una lista todos los
-- factores de dicho número.
-- Se debe utilizar la definición
-- de listas por comprensión.
factores :: Int->[Int]
factores n = [x | x <- [1..div n 2], mod n x == 0] ++ [n]
-- Implementar una función que diga si un número es primo.
-- Para ello se debe utilizar la función
-- que calcula el número de factores de un número (ejercicio f).
esPrimo :: Int -> Bool
esPrimo n = (length (factores n)) == 2
-- Implementar una función que diga
-- cuántos caracteres en mayúscula están contenidos
-- en una frase dada.
-- Se deberá utilizar la definición de listas por comprensión.
cuantasMayusculas :: [Char] -> Int
cuantasMayusculas string = length ([c | c <- string, isUpper c])
-- Implementar una función que dada una tupla de tres elementos, donde cada uno de
-- ellos es a su vez una tupla de dos elementos de tipo String e Int respectivamente,
-- retorne el primer elemento de cada tupla interna. Se deberá utilizar ajuste de patrones.
primerElemento :: ((String, Int), (String, Int), (String, Int)) -> [String]
primerElemento ((x1, y1), (x2, y2), (x3, y3)) = [x1, x2, x3]
-- Implementar una función que devuelve True si la suma de los cuatro primeros
-- elementos de una lista de números enteros es un valor menor a 10 y devolverá False
-- en caso contrario. Se deberá utilizar ajuste de patrones.
sumaMayor10 :: [Int] -> Bool
sumaMayor10 l = (sum (take 4 l)) < 10
-- Implementar una función que dado un carácter,
-- que representa un punto cardinal,
-- devuelva su descripción. Por ejemplo, dado ‘N’ devuelva “Norte”
puntoCardenal :: Char -> String
puntoCardenal 'N' = "Norte"
puntoCardenal 'S' = "Sur"
puntoCardenal 'E' = "Este"
puntoCardenal 'O' = "Oeste"
-- Implementar una función que dada una frase
-- retorne un mensaje donde se indique cuál
-- es la primera y última letra de la frase original.
procesarFrase :: [Char] -> [Char]
procesarFrase frase = "La primera letra de la frase ''" ++ frase ++ "'' es '" ++ [frase!!0] ++ "' y la ultima letra es '" ++ [last frase] ++ "'"
-- Implementar una función que dado un número entero devuelva mensajes indicando en
-- qué rango de valores se encuentra dicho número (menor de 10, entre 10 y 20 o mayor
-- de 20). Se debe utilizar definiciones locales.
rango20 :: Int -> [Char]
rango20 n =
if n < 10 then mensaje1
else if (n >= 10) && (n <= 20) then mensaje2
else mensaje3
where
mensaje1 = "El valor de entrada es menor que 10"
mensaje2 = "El valor de entrada es mayor o igual a 10 y menor o igual a 20"
mensaje3 = "El valor de entrada es mayor que 20"
-- Implementar una función que dada una cadena de caracteres y un carácter, indique el
-- número de apariciones del carácter en la cadena. No se debe utilizar recursividad, sí
-- ajuste de patrones. Pista: utilizar la definición de listas por comprensión.
contarAparicion :: String -> Char -> Int
contarAparicion [] c = 0
contarAparicion str c = length ([x | x <- str, x == c])
---------------------- TEMA 4 ----------------------
-- Implementa una función en Haskell que elimine de una lista de enteros aquellos
-- números múltiplo de x.
-- listas por comprensión
eliminarMultiplo1 :: [Int] -> Int -> [Int]
eliminarMultiplo1 l x = [e | e <- l, mod e x /= 0]
-- no final
eliminarMultiplo2 :: [Int] -> Int -> [Int]
eliminarMultiplo2 [] n = []
eliminarMultiplo2 (x:xs) n
| mod x n == 0 = new_rest
| otherwise = x:new_rest
where new_rest= eliminarMultiplo2 xs x
-- final
eliminarMultiplo3 :: [Int] -> Int -> [Int] -> [Int]
eliminarMultiplo3 [] x ac = ac
eliminarMultiplo3 (e:rest) x ac
| (mod e x) == 0 = eliminarMultiplo3 rest x ac
| otherwise = eliminarMultiplo3 rest x (ac ++ [e])
-- Dada la siguiente definición de función
-- doble :: Int -> Int
-- doble x = x + x
-- ¿Cómo cambiaría la definición utilizando expresiones lambda?
doubl = (\x -> x + x)
-- Se pide una función en Haskell
-- que dada una lista de números enteros obtenga un
-- número entero con el resultado de
-- calcular el doble de cada uno de los elementos de la
-- lista original y sumarlos todos.
-- Se piden diferentes versiones de la misma función:
-- Con recursividad no final
sumarDouble1 :: [Int] -> Int
sumarDouble1 [] = 0
sumarDouble1 (x:xs) = (doubl x) + (sumarDouble1 xs)
-- Con recursividad final
sumarDouble2 :: [Int] -> Int -> Int
sumarDouble2 [] ac = ac
sumarDouble2 (x:xs) ac = sumarDouble2 xs ((doubl x) + ac)
-- Utilizando expresiones lambda u orden superior (se puede hacer uso de la
-- función predefinida de Haskell map)
sumarDouble3 :: [Int] -> Int
sumarDouble3 l = foldr (+) 0 (map(doubl) l)
-- Implementa una función que sume los cuadrados de los números pares contenidos en
-- una lista de números enteros.
-- Una versión que haga uso de las funciones de orden superior de
-- listas map y filter para definir la nueva función.
sumarCuadrado1 :: [Int] -> Int
sumarCuadrado1 l = sum (map (^2) (filter even l))
-- Una versión que utilice la definición
-- de listas por comprensión.
sumarCuadrado2 :: [Int] -> Int
sumarCuadrado2 l = sum [x^2 | x <- l, even x]
-- Dada una lista de enteros, implementar una función para devolver tuplas formadas por
-- los elementos (sin repetir) de la lista, junto con la primera posición en la que aparecen.
primeraPos :: [Int] -> [(Int, Int)]
primeraPos l = filter (\(ee, ii) -> all (\(eee, iii) -> (eee /= ee) || (ii <= iii)) tuples) tuples
where tuples = [(e, idx) | (e,idx) <- enumerate l]
where enumerate x = zip x [1..]
-- Implementar en Haskell una función que
-- calcule el número de secuencias de ceros que
-- hay en una lista de números
secuenciaCeros :: [Int] -> Int
secuenciaCeros [] = 0
secuenciaCeros [0] = 1
secuenciaCeros [_] = 0
secuenciaCeros (x:y:zs) = if (x == 0 && y /= 0) then 1 + secuenciaCeros (y:zs) else secuenciaCeros (y:zs)
-- Implementar una función en Haskell
-- que reciba una lista de números enteros y devuelva
-- dos listas: una con los elementos sin repetir
-- y otra con los elementos que están repetidos.
partirRepetido :: [Int] -> ([Int], [Int])
partirRepetido l = foldl (\(ns,rs) x -> if (repetido x) then (ns++[x],rs) else (if all (\y -> y /= x) rs then (ns,rs++[x]) else (ns,rs))) ([],[]) l
where repetido x = length (filter (\y -> (y == x)) l) == 1
-- Dada una lista de números enteros
-- implementar una función que devuelva una lista con
-- los n elementos mayores de la lista original.
nMayores :: [Int] -> Int -> [Int]
nMayores l n = [x | x <- l, length (filter (>x) l) < n]
-- Implementa una función incluye en Haskell
-- que reciba dos listas de números enteros y
-- nos diga si la primera de las listas
-- está contenida en la segunda. Se dice que una lista
-- está contenida en otra si los elementos
-- de la primera aparecen dentro de la segunda, en
-- el mismo orden y de forma consecutiva.
lista_contains :: [Int] -> [Int] -> Bool
lista_contains [] _ = True
lista_contains _ [] = False
lista_contains (x:xs) (y:ys) = (x == y && xs == (take (length xs) ys)) || (lista_contains (x:xs) ys)
-- Dada una lista de enteros,
-- se pide implementar una función que ordene dicha lista de
-- menor a mayor utilizando un algoritmo de inserción.
-- Dicho algoritmo de inserción
-- consiste en recorrer la lista L,
-- insertando cada elemento L[i] en el lugar correcto entre
-- los elementos ya ordenados L[1] ,...,L[i-1].
insertar_uno :: Int -> [Int] -> [Int]
insertar_uno num [] = [num]
insertar_uno num (x:xs) = if (num < x) then num:x:xs else x:(insertar_uno num xs)
insert_sort :: [Int] -> [Int]
insert_sort l = foldr (\x l2 -> insertar_uno x l2) [] l
-- Implementa una función polimórfica en Haskell
-- que reciba 2 listas y vaya cogiendo un
-- elemento de la primera y dos de la segunda,
-- creando una lista final de ternas. En caso
-- de que una de las dos listas se acabe,
-- mostrará la lista de ternas construidas hasta ese
-- momento
concat_one_dos [] _ = []
concat_one_dos _ [] = []
concat_one_dos (x:xs) (y:z:zs) = (x,y,z):concat_one_dos xs zs
-- Se pide una función polimórfica en Haskell
-- que dado un elemento y una lista añada
-- dicho elemento al final de la lista.
insertar_final :: a -> [a] -> [a]
insertar_final n lista = lista ++ [n]
-- Mediante la programación de orden superior
-- se pide implementar una de las funciones
-- predefinidas en la librería estándar de Haskell:
-- la función zipWith.
-- Esta función recibe
-- como parámetros una función y dos listas
-- y une ambas listas aplicado la función entre
-- los correspondientes parámetros.
zipWith_ :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith_ f l1 l2 = [f x y |(x,y) <- zip l1 l2]
-- Define una función polimórfica
-- que sea capaz de invertir los elementos de una lista.
-- Se piden diferentes versiones:
-- recursividad no final
invertir_lista1 :: [a] -> [a]
invertir_lista1 [] = []
invertir_lista1 (x:xs) = invertir_lista1 xs ++ [x]
-- recursividad de cola o final
invertir_lista2 :: [a] -> [a] -> [a]
invertir_lista2 [] l = l
invertir_lista2 (x:xs) l = invertir_lista2 xs (x:l)
-- Utilizando la función de orden superior foldr
invertir_lista3 :: [a] -> [a]
invertir_lista3 l = foldr (\x xs -> xs ++ [x]) [] l
-- Define una función polimórfica
-- que sea capaz de invertir
-- los elementos de una lista de listas.
invertir_lista_lista :: [[a]] -> [[a]]
invertir_lista_lista l = map (invertir_lista3) (invertir_lista3 l)
-- Implementar la función predefinida de la librería estándar flip.
-- Esta función lo que hace es recibir una función
-- y devolver otra función que es idéntica a la función original,
-- salvo que intercambia los dos primeros parámetros.
flip_ :: (a -> b -> c) -> b -> a -> c
flip_ f y x = f x y
-- Implementar la función polimórfica predefinida de la librería estándar map.
-- Esta función lo que hace es recibir una función
-- y una lista y devuelve la lista resultante de aplicar la
-- función a cada elemento de la lista original.
map_ :: (a -> b) -> [a] -> [b]
map_ f l = [f x | x <- l]
---------------------- TEMA 5 ----------------------
-- Parte 1
-- Se pide una función que dada una lista de racionales,
-- donde cada racional se define como
-- dos números enteros (numerador y denominador),
-- y un número racional,
-- devuelva otra lista
-- con todos los racionales equivalentes al dado.
-- Empleando type
type Racional1 = (Int, Int)
eq_lista1 :: [Racional1] -> Racional1 -> [Racional1]
eq_lista1 l (n1,n2) = [(x,y) | (x,y) <- l, n1*y == n2*x]
-- Empleando data
type Numerador = Int
type Denominador = Int
data Racional2 = R (Numerador,Denominador)
eq_lista2 :: [Racional2] -> Racional2 -> [Racional2]
eq_lista2 l (R (n1,n2)) = [(R (x,y)) | (R (x,y)) <- l, n1*y == n2*x]
instance Show Racional2 where
show (R (n1,n2)) = "R ("++ Prelude.show(n1) ++ "," ++ Prelude.show(n2)++ ")"
-- b)
-- Función que dado un punto de coordenadas
-- y una dirección (Norte, Sur, Este u Oeste)
-- mueva el punto hacia la dirección indicada.
-- Un ejemplo de aplicación de la función sería:
type Coordenada = (Float,Float)
data PuntoCardinal = Norte | Sur | Este | Oeste deriving Show
mover:: Coordenada -> PuntoCardinal -> Coordenada
mover (x,y) Norte = (x,y+1)
mover (x,y) Sur = (x,y-1)
mover (x,y) Este = (x+1,y)
mover (x,y) Oeste = (x-1,y)
-- Función que dados dos puntos de coordenadas
-- indique cuál está más al sur.
-- Ejemplos de aplicación de la función son:
masSur :: Coordenada -> Coordenada -> Coordenada
masSur (x1,y1) (x2,y2)= if(y1 > y2) then (x2,y2) else (x1,y1)
-- Función que calcule la distancia entre dos puntos
distancia :: Coordenada -> Coordenada -> Float
distancia (x1,y1) (x2,y2) = sqrt ((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1))
-- Función que dado un punto y una lista de direcciones,
-- retorne el camino que forman todos los puntos
-- después de cada movimiento sucesivo desde el punto original
camino :: Coordenada -> [PuntoCardinal] -> [Coordenada]
camino (x,y) l = foldl (\r dir -> if (r == []) then r ++ [mover (x,y) dir] else r ++ [mover (last r) dir]) [] l
-- Definir una función que dado un día de la semana,
-- indique si éste es o no laborable.
-- Para representar el día de la semana
-- se deberá crear un nuevo tipo enumerado.
data Dia = Lunes|Martes|Miercoles|Jueves|Viernes|Sabado|Domingo
es_laborable Sabado = False
es_laborable Domingo = False
es_laborable _ = True
-- La empresa RealTimeSolutions, Inc.
-- está trabajando en un controlador para una central domótica.
-- El controlador recibe información
-- de termostatos situados en diferentes
-- habitaciones de la vivienda
-- y basándose en esta información,
-- activa o desactiva el aire acondicionado
-- en cada una de las habitaciones.
-- Los termostatos pueden enviar la información
-- sobre la temperatura en grados Celsius o Fahrenheit.
-- A su vez, los aparatos de aire acondicionado
-- reciben dos tipos de órdenes:
-- apagar y encender (on y off).
-- Definir un tipo de datos para representar
-- las temperaturas en ambos tipos de unidades.
data Temperatura = Celsius Double | Fahrenheit Double deriving Show
data Estado = On|Off deriving Show
-- Definir una función convert
-- que dada una temperatura
-- en grados Celsius la convierta
-- a grados Fahrenheit y viceversa.
convertir :: Temperatura -> Double
convertir (Celsius temp) =(temp * (9/5) + 32)
convertir (Fahrenheit temp) =((temp-32) * 5/9)
-- Definir un tipo de datos
-- para representar las órdenes a los aparatos de a/a
controlar :: Temperatura -> Estado
controlar (Celsius temp) = if(temp<28) then On else Off
controlar (Fahrenheit temp) = controlar (Celsius (convertir (Fahrenheit temp)))
-- Definir un tipo moneda para representar euros y dólares USA.
-- Definir una función que convierte entre ambas monedas
-- sabiendo que el factor de conversión de euros a dólares es 1.14.
data Moneda = Euro | Dolar
convertir_moneda :: Moneda -> Double -> Double
convertir_moneda Euro n = n * 1.14
convertir_moneda Dolar n = n / 1.14
-- Dada el siguiente tipo de datos recursivo
-- que representa expresiones aritméticas
data Expr = Valor Integer
|Expr :+: Expr
|Expr :-: Expr
|Expr :*: Expr
evaluar :: Expr -> Integer
evaluar (Valor n) = n
evaluar (e1 :+: e2) = evaluar(e1) + evaluar(e2)
evaluar (e1 :-: e2) = evaluar(e1) - evaluar(e2)
evaluar (e1 :*: e2) = evaluar(e1) * evaluar(e2)
-- Se pide una función para calcular
-- el número de constantes de una expresión
contar :: Expr -> Integer
contar (Valor n) = 1
contar (e1 :+: e2) = contar(e1) + contar(e2)
contar (e1 :-: e2) = contar(e1) + contar(e2)
contar (e1 :*: e2) = contar(e1) + contar(e2)
------------Parte 2--------------------------------------
-- Se quiere ordenar los elementos de una lista
-- (cuyos elementos son comparables)
-- mediante el algoritmo del quicksort.
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) = (quicksort [y | y <- xs, y < x]) ++ x:(quicksort [y | y <- xs, y > x])
-- Se pide implementar una función que dada un número
-- (de cualquier tipo que soporte la operación de división)
-- y una lista de números del mismo tipo,
-- divida a ese número por cada uno de los elementos
-- contenidos en la lista y devuelva una lista con el resultado.
-- Ejemplos de aplicación de la función son:
divide :: (Fractional a) => a -> [a] -> [a]
divide n l = [x / n | x <- l]
-- Dado un nuevo tipo de datos
-- para representar un árbol binario de cualquier tipo
data Arbol a = AV | Rama (Arbol a) a (Arbol a)
instance (Show a) => Show (Arbol a) where
show AV = "*"
show (Rama l r d) = "(" ++ show l ++ "-|" ++ show r ++ "|-"++ show d ++ ")"
-- Se pide definir una función que calcule el espejo de un árbol.
espejo :: Arbol a -> Arbol a
espejo AV = AV
espejo (Rama l r d) = Rama (espejo d) r (espejo l)
-- Se quiere poder mostrar por pantalla
-- los datos de los estudiantes matriculados en una
-- universidad que pertenezcan a alguna
-- de las asociaciones de ésta
-- (culturales, deportivas, de representación estudiantil, etc.).
-- Para ello se deberán
-- crear nuevos tipos de datos que representen
data Titulacion = Grado_II | Grado_II_ADE | Grado_ADE deriving Show
type Nombre = String
data Estudiante = Est Nombre Titulacion deriving Show
data Asociation = Culturales | Deportivas | Representante deriving Show
type Estudiante_Matriculados = [Estudiante]
type Est_ASO = [(Estudiante, Asociation)]
instance Eq Estudiante where
(Est n1 t1) == (Est n2 t2) = n1 == n2
in_aso :: Estudiante -> [Estudiante] -> Bool
in_aso _ [] = False
in_aso e (x:xs) = if e == x then True else in_aso e xs
estidiantes_in_aso :: Est_ASO -> [Estudiante]
estidiantes_in_aso a = map (\(x,y) -> x) a
mostrar :: (Estudiante_Matriculados, Est_ASO) -> [Estudiante]
mostrar (m,a) = [e | e <- m, in_aso e (estidiantes_in_aso a)]
-- Se quiere poder representar una fecha de la siguiente forma:
-- dd/mm/aaaa, para ello se deberá
-- crear un nuevo tipo de datos en Haskell.
-- Por ejemplo, si se crea un nuevo tipo de datos
-- cuyo constructor de datos es Fecha,
-- en el intérprete al poner fechas concretas nos
-- devolvería la representación de la fecha
-- que hayamos definido
data Fecha = F Int Int Int
instance Show Fecha where
show (F day month year) = show day ++ "/" ++ show month ++ "/" ++ show year
-- Teniendo en cuenta el nuevo tipo de datos Fecha
-- definido anteriormente,
-- se pide una función que sea capaz de comparar dos fechas.
-- Ejemplos de aplicación de la función serían:
instance Eq Fecha where
(F d1 m1 y1) == (F d2 m2 y2) = (d1 == d2) && (m1 == m2) && (y1 == y2)
-- Teniendo en cuenta la definición de la función qs
-- del apartado (b) de este listado de ejercicios,
-- se pide ordenar una lista de fechas mediante quicksort.
instance Ord Fecha where
compare (F d1 m1 y1) (F d2 m2 y2) = if ((compare y1 y2) == EQ) then (if ((compare m1 m2) == EQ) then compare d1 d2 else compare m1 m2) else compare y1 y2
-- Se pide crear una nueva clase de tipos,
-- llamada Coleccion, para representar colecciones
-- de datos de cualquier tipo,
-- donde los tipos pertenecientes a esta clase
-- tendrán el siguiente comportamiento
class Collection c where
-- función para saber si la colección está vacía
esVacia :: c -> Bool
-- insertará un nuevo elemento en la colección.
insertar :: a -> c -> c
-- devolverá el primer elemento de la colección.
primero :: c -> a
-- eliminará un elemento de la colección.
eliminar :: c -> c
-- devolverá el número de elementos de la colección.
size :: c -> Int
data Pila a = Pil [a] deriving Show
data Cola a = Col [a] deriving Show
-- instance Collection (Pila a) where
-- esVacia (Pil l) = (length l == 0)
-- insertar e (Pil l) = Pil (e:l)
-- dos recursivadad pura y dura
calcular :: [Int] -> [Int]
calcular [] = []
calcular [_] = []
calcular (x:y:zs) = (x+y):(calcular (y:zs))
triangulo :: Int -> [Int]
triangulo 0 = [1]
triangulo 1 = [1, 1]
triangulo 2 = [1, 2 ,1]
triangulo n = 1:(calcular(triangulo (n-1))) ++ [1]
-- la primera
esta_en_resultado :: (Eq a) => a -> [(a,Int)] -> Bool
esta_en_resultado _ [] = False
esta_en_resultado e ((x,idx):es) = if (e == x) then True else esta_en_resultado e es
primeraAparicion :: (Eq a) => [a] -> [(a,Int)]
primeraAparicion l = foldl (\resultado (e,idx) -> if (esta_en_resultado e resultado) then resultado else resultado ++ [(e,idx)]) [] (zip l [1..])
-- tipo de datos
data Monomio = M (Int, Int)
data Polinomio = P [Monomio]
-- a) (0.5 puntos) Instanciar a la clase Show ambos tipos
instance Show Monomio where
show (M (a, b)) = (show a) ++ "*x^" ++ (show b)
instance Show Polinomio where
show (P (m:ms)) = show m ++ (if ms == [] then "" else "+" ++ show (P ms))
-- b) (0.75 puntos) Instanciar a la clase Eq ambos tipos.
-- Dos monomios serán iguales cuando sean iguales sus coeficientes
-- y sus exponentes.
-- Dos polinomios serán iguales cuando tengan los mismos monomios.
instance Eq Monomio where
(M (a1,b1)) == (M (a2,b2)) = (a1 == a2 && b1 == b2)
instance Eq Polinomio where
(P []) == (P []) = True
(P []) == (P _) = False
(P _) == (P []) = False
(P (m1:ms1)) == (P (m2:ms2)) = (m1 == m2) && (ms1 == ms2)
-- c) (1 punto) Instanciar a la clase Ord ambos tipos.
-- Un monomio es mayor que otro cuando tiene mayor exponente
-- o bien cuando a igualdad de exponente,
-- uno tiene un coeficiente mayor que el otro.
-- Un polinomio será mayor que otro cuando su monomio
-- de mayor grado sea mayor que el monomio de mayor grado del otro.
-- En caso de igualdad, se compararían los siguientes monomios
instance Ord Monomio where
compare (M (a1,b1)) (M (a2,b2)) = if cmp_b == EQ then compare a1 a2 else cmp_b where cmp_b = compare b1 b2
instance Ord Polinomio where
compare (P []) (P []) = EQ
compare (P []) (P _) = LT
compare (P _) (P []) = GT
compare (P (m1:ms1)) (P (m2:ms2)) = if cmp_m == EQ then compare ms1 ms2 else cmp_m where cmp_m = compare m1 m2
-- d) (0.75 puntos) Implementar la función evaluaPolinomio,
-- que recibirá un valor entero y un polinomio
-- y nos devolverá su resultado
evaluaPolinomio :: Int -> Polinomio -> Int
evaluaPolinomio x (P []) = 0
evaluaPolinomio x (P (M (a,b):ps)) = (a * (x^b)) + (evaluaPolinomio x (P ps))
-- e) (1 punto) Implementar la función insertaMonomio,
-- que recibirá un monomio y un polinomio
-- y lo insertará en el mismo.
concat_p :: Monomio -> Polinomio -> Polinomio
concat_p m (P l) = P (m:l)
insertaMonomio :: Monomio -> Polinomio -> Polinomio
insertaMonomio m (P []) = P [m]
insertaMonomio m (P (x:xs)) = if m > x then (P (m:x:xs)) else concat_p x (insertaMonomio m (P xs))
-- f) (1 punto) Implementar la función eliminaMonomio,
-- que recibirá un número entero
-- (representativo del exponente de un monomio)
-- y un polinomio y eliminará el monomio con dicho exponente
-- (en el caso de que estuviese).
eliminaMonomio :: Int -> Polinomio -> Polinomio
eliminaMonomio n (P []) = (P [])
eliminaMonomio n (P ((M (a,b)):ms))
| n == b = P ms
| n > b = P ((M (a,b)):ms)
| otherwise = concat_p (M (a,b)) (eliminaMonomio n (P ms))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment