Divisibilidad y congruencia
Taller de ´
Algebra I
Algoritmo de la divisi´
on
Teorema
Dados
a
,
d
∈
Z
,
d
6= 0, existen ´
unicos
q
,
r
∈
Z
tales que
I a=qd+r,I 0≤r<|d|.
Idea de la demostraci´
on:
(caso
a
≥
0,
d
>
0). Por inducci´
on en
a
.
I Si 0≤a<d, tomamosq= 0,r =a.
I Si no, dividimosa−dpord. Eso da un cocienteq0y un restor0. Tomamosr =r0,
q=q0+ 1.
Ejercicio
Implementar la funci´
on
division :: Integer -> Integer -> (Integer, Integer)
N´
umeros primos
Definici´
on
Un entero
p
>
1 es
primo
si ning´
un natural
k
tal que 1
<
k
<
p
divide a
p
.
¿C´
omo determinamos en Haskell si un n´
umero entero mayor que cero es primo? Una
posibilidad ser´ıa buscar sus divisores.
divisores
(
n
) =
{
k
∈
Z
|
1
≤
k
≤
n
y
k
|
n
}
¿C´
omo lo hacemos de forma recursiva?
¿Sirve hacer recursi´
on sobre
n
?
Idea: definir una lista “parcial” de divisores:
divParcial
(
n
,
m
) =
{
k
∈
Z
|
1
≤
k
≤
m
y
k
|
n
}
En este caso, har´ıamos recursi´
on sobre
m
.
N´
umeros primos
Ejercicios
(a) Implementar la funci´on
divParcial :: Integer -> Integer -> [Integer]
divParcial n mdebe funcionar bien siempre que0 < m≤ n.
(b) Utilizando divParcial, programar
divisores :: Integer -> [Integer] (c) Utilizando divisores, programar
Algoritmo de Euclides
El
algoritmo de Euclides
calcula el m´
aximo com´
un divisor entre dos n´
umeros
a
,
b
∈
Z
.
Se basa en que si
a
,
b
∈
Z
y
k
∈
Z
es un n´
umero cualquiera, entonces
(
a
:
b
) = (
a
+
kb
:
b
)
Si
q
y
r
son el cociente y el resto de la divisi´
on de
a
por
b
, tenemos
a
=
qb
+
r
, entonces
a
−
qb
=
r
. Por lo tanto,
(
a
:
b
) = (
a
−
qb
:
b
) = (
r
:
b
) = (
b
:
r
)
Por ejemplo, para calcular (30 : 48):
1 (30 : 48) — Dividimos 30 por 48,q= 0,r= 30 2 = (48 : 30) — Dividimos 48 por 30,q= 1,r= 18 3 = (30 : 18) —q= 1,r= 12 4 = (18 : 12) —q= 1,r= 6 5 = (12 : 6) —q= 2,r= 0 6 = (6 : 0) 7 = 6
Algoritmo de Euclides
El
algoritmo de Euclides
calcula el m´
aximo com´
un divisor entre dos n´
umeros
a
,
b
∈
Z
.
Se basa en que si
a
,
b
∈
Z
y
k
∈
Z
es un n´
umero cualquiera, entonces
(
a
:
b
) = (
a
+
kb
:
b
)
Si
q
y
r
son el cociente y el resto de la divisi´
on de
a
por
b
, tenemos
a
=
qb
+
r
, entonces
a
−
qb
=
r
. Por lo tanto,
(
a
:
b
) = (
a
−
qb
:
b
) = (
r
:
b
) = (
b
:
r
)
Ejercicio
Programar la funci´
on
mcd :: Integer -> Integer -> Integer
que utilice el algoritmo de Euclides y calcule el m´
aximo com´
un divisor entre dos n´
umeros.
Clases de congruencia
Llamamos
clase de congruencia
al conjunto de todos los enteros congruentes a un cierto
n´
umero, m´
odulo otro.
Ejemplos:
I {a∈Z|a≡1 (mod 3)}={. . . ,−2,1,4,7,10, . . .},
I {a∈Z|a≡0 (mod 9)}={. . . ,−18,−9,0,9,18,27, . . .}.
Cada clase de congruencia es un
conjunto infinito
de enteros tales que entre dos
elementos consecutivos del conjunto hay siempre la misma diferencia.
Consideraremos tambi´
en una clase de congruencia v´
alida al conjunto vac´ıo (
∅
).
En Haskell, vamos a modelar las clases de congruencia con el siguiente tipo de datos:
d a t a C l a s e C o n g r = V a c i o | C o n g r u e n t e s A I n t e g e r I n t e g e r d e r i v i n gS h o w
As´ı, por ejemplo,
I {a∈Z|a≡1 (mod 3)}esCongruentesA 1 3,
Clases de congruencia: Ejercicios
Ejercicios
A partir del tipo de datos
d a t a C l a s e C o n g r = V a c i o | C o n g r u e n t e s A I n t e g e r I n t e g e r d e r i v i n g S h o w
programar las siguientes funciones:
1 multiplo :: Integer -> Integer -> Bool, que determine si el primero de sus argumentos es m´ultiplo del segundo. (¡Cuidado con el 0!).
2 congruentes :: Integer -> Integer -> Integer -> Bool, que verifique si sus dos primeros argumentos son congruentes m´odulo el tercero. Asumir que el tercer argumento es distinto de cero.
3 pertenece :: Integer -> ClaseCongr -> Bool, que determine si un entero forma parte de una clase de congruencia. Por ejemplo:
pertenece 13 Vacio False
pertenece 13 (CongruentesA 5 4) True
4 incluido :: ClaseCongr -> ClaseCongr -> Bool, que dadas dos clases de congruencia
P1yP2, determine siP1⊆P2. Por ejemplo:
Clases de tipos: Ejercicios
Ejercicios
1 Hacer que ClaseCongrsea instancia deShow programando la funci´on show para que las clases de congruencia se muestren de esta forma:
Prelude> C o n g r u e n t e s A 3 8 { a en Z | a = 3 (mod 8) }
Prelude> V a c i o {}
2 Programar iguales :: ClaseCongr -> ClaseCongr -> Bool, que determina si dos clases de congruencia tienen los mismos elementos. Por ejemplo,
iguales (CongruentesA 22 5) (CongruentesA 2 5) True.
3 Hacer que ClaseCongrsea instancia deEq, utilizando la igualdad programada anteriormente.
Recordar:
I Para que un tipo t sea instancia de Show, hay que definir una funci´on
show :: t -> String.
I Para que un tipo t sea instancia de Eq, hay que definir una funci´on
Ejercicios
1 SiP1yP2son clases de congruencia, definimos su suma como
P1+P2={(a+b)|a∈P1, b∈P2}
Verificar que la suma de dos clases de congruencia es tambi´en una clase de congruencia, y programar una funci´onsuma :: ClaseCongr -> ClaseCongr -> ClaseCongr que calcule esta suma.
Por ejemplo, suma (CongruentesA 3 6) (CongruentesA 2 4) CongruentesA 5 2. 2 Verificar que la intersecci´on entre dos clases de congruencia (P1∩P2) tambi´en es una clase
de congruencia, e implementar
interseccion :: ClaseCongr -> ClaseCongr -> ClaseCongr, que calcule esta intersecci´on.
3 Implementar tieneSolucion :: Integer -> ClaseCongr -> Boolque diga si una ecuaci´on de congruencia tiene soluci´on. Es decir,tieneSolucion t (CongruentesA a m)
Divisibilidad: Bonus track
1 Adaptardivisionparaa<0 od<0. Observaci´on: las funcionesdivymodde Haskell no coinciden con el algoritmo de divisi´on cuandod<0. Ver tambi´enquotyrem.
2 (a) ImplementarnoTieneDivisoresHasta :: Integer -> Integer -> Bool.
noTieneDivisoresHasta m ndaTruesii ning´un n´umero entre2ymdivide an.
(b) UtilizandonoTieneDivisoresHasta, programaresPrimo' :: Integer -> Bool. 3 (a) Escribir una funci´on primosHasta :: Integer -> [Integer] que dadon>0
devuelva la lista de todos los primos positivos menores o iguales quen.
(b) Escribir una funci´on hayPrimosEntre :: Integer -> Integer -> Bool tal que
hayPrimosEntre a besTrue si y solo si hay alg´un primopcona≤p≤b.
(c) Escribir una funci´on bertrand :: Integer -> Bool que dadon≥1 diga si hay alg´un primo entreny 2n. No vale usar el postulado de Bertrand1.
4 Conjetura(Christian Goldbach, 1742): Todo n´umero par mayor que 2 puede escribirse
como suma de dos n´umeros primos.
(a) Dado un n´umero naturaln, determinar si puede escribirse como suma de dos n´umeros primos.
(b) En funci´on de este ejercicio, ¿c´omo ser´ıa un programa en Haskell para testear la conjetura de Goldbach hasta un cierto punto?