upload diverse filer

This commit is contained in:
2025-12-10 13:13:05 +01:00
parent 41700ebeda
commit fe9e35efa5
65 changed files with 77423 additions and 2530 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -668,7 +668,7 @@ Er et polynomium $Z^n=w$
$Z,w in CC, n in ZZ_(>=0)$
$
Z= root(n, |w|) dot e^(i ((a r g(w))/n) + p (2 pi)/n), p = {0,dots,n-1}
Z= root(n, |w|) dot e^(i ((a r g(w))/n + p (2 pi)/n)), p = {0,dots,n-1}
$
#example()[
@@ -699,7 +699,7 @@ Et n'te grads polynomie har n komplekse rødder regnet med multiplicitet.
Man kan omskrive alle polynomier som et produkt af førstegradspolynomier.\
Hvis $p(z)$ har rødder $lambda_1, dots, lambda_n$, kan det omskrives til:
$
P(z)=a_n(z-lambda_1) dot dots dot (z-lambda_n)
P(z)=a_n (z-lambda_1) dot dots dot (z-lambda_n)
$
eller med multiplicitet:
$
@@ -840,7 +840,7 @@ sum^(n-1)_(k=1)k=((n-1)(n-1+1))/2=((n-1)dot n)/2
$
$
sum^(n)_(k=1)k=underbrace(1+2+3+dots+(n-2)+(n-1)+, sum^(n-1)_(k=1)k) n
sum^(n)_(k=1)k=underbrace(1+2+3+dots+(n-2)+(n-1), sum^(n-1)_(k=1)k) + n
$
$
sum^(n)_(k=1)k&=sum^(n-1)_(k=1)k + n\
@@ -1022,7 +1022,7 @@ $u = a_1+b_1Z\ v=a_2+b_2Z$
Betragt
$
u+ alpha dot v &= (a_1+b_1Z)+alpha (a_2 + b_2 Z)
u+ alpha dot v &= (a_1+b_1Z)+alpha (a_2 + b_2 Z)\
&= a_1 + b_1Z + alpha a_2+ alpha b_2Z = underbrace((a_1 + alpha a_2), a in CC) + underbrace((b + alpha b_2), b in CC)Z
$
]
@@ -1164,7 +1164,7 @@ $f$ er injektiv hvis og kun hvis $ker(f)={0}$ (og $f$ er lineær)
Derfor, find nulrummet. $"rref"(amat(f, gamma, beta))=mat(1,0), x_1 = 0$ dvs.
$amat(f, gamma, beta)) underbrace(vec(0,t), = t vec(0,1))=0$ for *alle* $t in RR$
$amat(f, gamma, beta) underbrace(vec(0,t), = t vec(0,1))=0$ for *alle* $t in RR$
$f(vec(0,1))=0$. Tilbage til normale koordinater.

View File

@@ -0,0 +1,142 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "8d87a703",
"metadata": {},
"outputs": [],
"source": [
"import sympy as sp\n"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "dffe7f14",
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$\\displaystyle \\left[\\begin{matrix}52 & -8 & -8\\\\-4 & 50 & 2\\\\-4 & 2 & 50\\end{matrix}\\right]$"
],
"text/plain": [
"Matrix([\n",
"[52, -8, -8],\n",
"[-4, 50, 2],\n",
"[-4, 2, 50]])"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"{60: 1, 48: 1, 44: 1}\n"
]
}
],
"source": [
"# Opgave 1\n",
"A = sp.Matrix([[52, -8, -8], [-4, 50, 2], [-4, 2, 50]])\n",
"display(A)\n",
"eigenvalsA = A.eigenvals()\n",
"print(eigenvalsA)\n"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "debdde8b",
"metadata": {},
"outputs": [
{
"data": {
"text/latex": [
"$\\displaystyle \\left[\\begin{matrix}9 & -2 & 1\\\\-1 & 10 & -1\\\\1 & -2 & 9\\end{matrix}\\right]$"
],
"text/plain": [
"Matrix([\n",
"[ 9, -2, 1],\n",
"[-1, 10, -1],\n",
"[ 1, -2, 9]])"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"[(8, 2, [Matrix([\n",
"[2],\n",
"[1],\n",
"[0]]), Matrix([\n",
"[-1],\n",
"[ 0],\n",
"[ 1]])]), (12, 1, [Matrix([\n",
"[ 1],\n",
"[-1],\n",
"[ 1]])])]\n",
"hej\n",
"Matrix([[2], [1], [0]])\n",
"Matrix([[-1], [0], [1]])\n",
"Matrix([[1], [-1], [1]])\n",
"Matrix([[12], [20], [-20]])\n"
]
}
],
"source": [
"# Opgave 2\n",
"\n",
"B = sp.Matrix([[9, -2, 1], [-1, 10, -1], [1, -2, 9]])\n",
"display(B)\n",
"eigenvectsB = B.eigenvects()\n",
"\n",
"print(eigenvectsB)\n",
"print(\"hej\")\n",
"print(eigenvectsB[0][2][0])\n",
"print(eigenvectsB[0][2][1])\n",
"print(eigenvectsB[1][2][0])\n",
"\n",
"print(sp.Matrix([[9, -2, 1], [-1, 10, -1], [1,-2,9]]) * sp.Matrix([2, 2, -2]))"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fa460b84",
"metadata": {},
"outputs": [],
"source": [
"# Opgave 3\n",
"\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,7 +1,7 @@
#import "@local/dtu-template:0.5.1":*
#show: dtu-math-assignment.with(
#show: dtu-note.with(
course: "01001",
course-name: "Mathematics 1a (Polytechnical Foundation)",
title: "Matrixalgebra og determinanter",
@@ -94,3 +94,49 @@ $
]
*Gange matricer sammen:*
Bygger videre før.
$
bold(A) in FF^(m times n), quad bold(B) in FF^(n times L)
$
Antal søjler i $bold(B)$ skal være lig med antal rækker i $bold(A)$.
$bold(B) = mat(bold(b_1),dots,bold(b_L))$
$
bold(A) dot bold(B) = mat(bold(A) dot bold(b_1), bold(A) dot bold(B_2), dots, bold(A) dot bold(b_L))
$
Bemærk $bold(A) dot bold(B) in FF^(m times L)$
#note-box()[
Bemærk: $bold(A) dot bold(B) eq.not bold(B) dot bold(A)$
]
= Lineære ligningssystem
$
cases(a_(11) x_1 + dots + a_(1 n) x_n = b_1, dots.v, a_(m 1) x_1 + dots + a_(m n) x_n = b_n)
$
Er det samme som:
$
mat(a_(11), dots, a_(1 n);dots.v;a_(m 1), dots, a_(m n)) dot vec(x_1, dots.v, x_n) = vec(b_1, dots.v, b_n)
$
#definition(title: "Identitetsmatrix")[
$
bold(I)_n = mat(1,0,dots,0;0,,,dots.v;dots.v,,,0;0,dots,0,1) in FF^(n times n)
$
Kaldes den $n times n$ identitetsmatrix
]
#definition(title: "7.3.1: Invers matrix")[
Givet $bold(A) in FF^(n times n)$ hvis der findes en matrix $bold(B) in FF^(n times n)$ således at $bold(A) dot bold(B) = bold(I)_n$ og $bold(B) dot bold(A) = bold(I)_n$, siges at $bold(A)$ er invers og $bold(B)$ kaldes $bold(A)$'s inverse matrix:
$
bold(B) = bold(A)^(-1)
$
Man finder den ved:
$
mat(bold(A),bold(I)_n; augment: #(-1)) arrow.long dots arrow.long mat(bold(I)_n, bold(A)^(-1);augment: #(-1))
$
]

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@ Section 6.4
= Binomial coefficient
From last week:
$C(n, k) = $ the number of k-combinations from an n-set. Or the number of ways to select k elements from an n-set. Or the number of k-subsets of an n-set. Formula: $n!/(k!-(n-k)!)=mat(n;k)$ for $0<=k<=n$
$C(n, k) = $ the number of k-combinations from an n-set. Or the number of ways to select k elements from an n-set. Or the number of k-subsets of an n-set. Formula: $n!/(k!(n-k)!)=mat(n;k)$ for $0<=k<=n$
== Pascal's triangle
@@ -175,4 +175,4 @@ $ (x+y)¹&=mat(1;0)dot x⁰ dot y¹ + mat(1;1)dot x¹ dot y⁰\
Therefore, the coefficient of $x^(n-k)y^k$ is $binom(n,k)$.
= Van der Mande
$mat(m+n;r)=sum^r_(k=0)mat(m;r-k) mat(n;k)$
$mat(m+n;r)=sum^r_(k=0)mat(m;r-k) mat(n;k)$

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,5 @@
#import "@local/dtu-template:0.5.1":*
#definition()[
Hej
]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 60 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,116 @@
#import("@local/dtu-template:0.5.1"):*
#show: dtu-note.with(
course: "01017",
course-name: "Discrete Mathematics",
title: "Polynomials and the Extended Euclidean Algorithm - Exercises",
date: datetime(year: 2025, month: 12, day: 4),
author: "Rasmus Rosendahl-Kaa",
semester: "Fall 2025"
)
= Exercise 6.16
Let $p(x) = sum^n_(k=0) c_k x^k$ be a polynomial if the coefficients $c_0, dots , c_n$ are all integers where $c_0 eq.not 0$ as well as $c_n eq.not 0$.
Let $QQ$ denominate the set of rational number, meaning fractions with integers in the numerator and the denominator. Then the following theorem is true:
If $a/b in QQ$ with $"gcd"(a,b) = 1$, and if $p(a/b)=0$, then it is true that $a | c_0$ and $b | c_n$.
/ a): Show by the help of the above that the polynomial $p(x)=x^2-2$ does not have any rational roots.
#solution()[
For $a | c_0$ and $b | c_n$ to be true, $a = 1,2$ and $b = 1$.
If $p(x)$ has integer roots, they would divide $c_0 "and" c_n$
Here, we already have the only numbers that can divide $c_0 "and" c_n$. But neither $P(2/1) "nor" P(1/1)$ equals 0, so that must mean $p(x)$ does not have any rational roots. Only $a=b=1$ would have $"gcd"(a,b)=1$, but $p(1/1)$ still doesn't equal 0, so that must mean that $p(x)$ doesn't have rational roots.
]
/ b): Conclude that $sqrt(2) in.not QQ$
#solution()[
$p(x)$ has roots: $-sqrt(2)$ and $sqrt(2)$. Because we have what values $a,b$ ($a=b=1$) could be in $p(x)$, we can see that $1/1 in QQ$, $"gcd"(1,1)=1$, and that $a | c_0$ and $b | c_n$.
But since we know that $sqrt(2)$ and $-sqrt(2)$ are roots, this means $p(sqrt(2))=p(-sqrt(2))=0$. But since we have that $1/1 eq.not sqrt(2)$, we can conclude that $sqrt(2) in.not QQ$.
]
/ c): Conclude in a similar fashion that $sqrt(5) in.not QQ$
#solution()[
We can observe a similar equation: $p(x)=x^2-5$. We can also observe that for the given theorem, then $a=b=1$ are the only value that they could have. But for similar reasons as before, $1/1 eq.not sqrt(5)$, so $sqrt(5) in.not QQ$.
]
/ d): Is it possible that $sqrt(5) sqrt(2) QQ$? We actually do not know that yet. Show that $sqrt(5) - sqrt(2)$ is a root of the polynomial $q(x) = x^4 14x^2 + 9$. Show that$sqrt(5) - sqrt(2) in.not QQ$.
#solution()[
$
p(sqrt(5)-sqrt(2)) = (sqrt(5)-sqrt(2))^4 - 14 dot (sqrt(5)-sqrt(2))^2 + 9\
$
$
(sqrt(5)-sqrt(2)) dot (sqrt(5)-sqrt(2)) &= sqrt(5)^2+sqrt(2)^2-2 dot sqrt(5) dot sqrt(2)\
&=5+2-2 dot sqrt(10) = 7 - 2 sqrt(10)
$
$
p(sqrt(5)-sqrt(2)) &= (7 - 2 sqrt(10)) dot (7 - 2 sqrt(10)) - 14 dot (7 - 2 sqrt(10)) + 9\
&= 49 + 4 sqrt(10)^2 - 28 sqrt(10) - 14 dot 7 + 28 sqrt(10) + 9\
&= 49+40-14 dot 7+9\
&=98 - 98 = 0
$
$sqrt(5)-sqrt(2)$ is a root.
The only $a,b$ we can have are $a=b=1$. 1 is not a root:
$
q(1)=1^4-14+9 = -4
$
Therefore $sqrt(5)-sqrt(2) in.not QQ$
]
/ e): (Extra, not in the curriculum) Prove the theorem in the beginning of the exercise. (Tip: Consider $p(a/b) = 0$ and multiply by the common denominator, such that all terms are integers. Thereafter use modulus arithmetic.)
= Exercise 6.17
We will examine the execution time of Euclids algorithm
/ a): Prove as function of $deg(f(x))$ and $deg(g(x))$, how many iteration Euclid's algorithm uses at most, when it is executed on $f(x)$ and $g(x)$.
#solution()[
Because we in the Euclidean Algorithm have that $deg(R_i) < deg(R_(i-1))$ aka the degree must always go down, and also have that $deg(R_1) < deg(M)$. Then the Euclidean Algorithm must use at most $deg(g(x))$ iterations, where $deg(g(x))<deg(f(x))$
]
/ b): Let $D(n)$ be an upper limit for the number of arithmetic operations it takes to execute a division of $f(x)$ by $g(x)$ with a remainder if $deg(f(x)), deg(g(x)) <= n$. By arithmetic operations we mean $+,,· "or" "/"$ of elements from the field, thus $RR$ or $CC$. Argue that $D(n) <= 2n^2$.
#solution()[
Imagine for the upper bound that $deg(f(x))=deg(g(x))=n$.
]
/ c):
/ d):
= Exercise 6.18
As usual with fractions, they can be reduced such that given $p(x)/q(x)$ if you by chance know that there exists a $t(x)$ such that $p(x)=t(x)p_1 (x)$ and $q(x)=t(x)q_1 (x)$, then we have:
$
p(x)/q(x)=(t(x)p_1 (x))/(t(x)q_1 (x)) = (p_1(x))/(q_1(x))
$
If you are just given a rational function $p(x)/q(x)$, describe a course of action to calculate the completely reduced fraction.
#solution()[
Calculate the roots of each of the functions, then divide the two. You would be able to remove all their common roots, and be left with a completely reduced fraction
]
= Exercise 6.19
Let $p(x)$ and $d(x)$ be polynomials both different from zero. Assume that $d(x) = d_1(x)d_2(x)$, where $"gcd"(d_1(x), d_2(x)) = 1$, and assume that $deg(p(x)) < deg(d(x))$. Show that there exists polynomials $p_1(x)$ and $p_2(x)$ such that
$
deg(p_1(x)) < deg(d_1(x)) "and" deg(p_2(x)) < deg(d_2(x))
$
and
$
p(x)/d(x)=(p_1(x))/(d_1(x)) + (p_2(x))/(d_2(x))
$
Tip: First multiply the wanted equation by $d(x)$
#solution()[
$
p(x)=p_1(x)d_2(x) + p_2(x)d_1(x)
$
]

View File

@@ -0,0 +1,221 @@
#import("@local/dtu-template:0.5.1"):*
#show: dtu-note.with(
course: "01017",
course-name: "Discrete Mathematics",
title: "Polynomials and the Extended Euclidean Algorithm",
date: datetime(year: 2025, month: 12, day: 4),
author: "Rasmus Rosendahl-Kaa",
semester: "Fall 2025"
)
An example of a polynomial
$
f(x) = x^2 - 4x+3\
g(x)= 2x-3\
h(x) = 7
$
The curve on the graph is called a parabola
What we say for polynomials with real coefficients also applies to the ones with complex coefficients
#definition(title: "Polynomial of degree n")[
$
P(x)=a_0 + a_1 x + a_2 x^2 + dots + a_n x^n, quad a_n eq.not 0, a_i in RR "or" CC
$
- $a_n$ is called the leading term
- $a_0$ is called the constant term.
- $n$ is the degree
]
#definition(title: "Addition of polynomials")[
Same $P(x)$ as before
$
Q(x) = b_0 + b_1 x + dots + b_m x^m, quad m <= n\
$
$
P(x) + Q(x) = (a_0 + b_0) + (a_1 + b_1) x + dots + (a_m + b_m)x^m\ + a_(m+1)x^(m+1) + dots + a_n x^n
$
$
deg(P(x) + Q(x)) <= n "with equality if" m < n
$
]
#definition(title: "Multiplication")[
Same $P(x), Q(x)$ as before
$
P(x) dot Q(x) = a_0 dot b_0 + (a_0 b_1 + a_1 b_0) x + (a_0 b_2 + a_1 b_1 + a_2 b_0) x^2 + dots +\
a_n b_m x^(n+m)
$
$
deg(P(x) dot Q(x)) = n+m = deg(P(x)) + deg(Q(x))
$
When multiplying you basically do:
$
P(x) dot Q(x) = a_0 dot Q(x) + a_1x dot Q(x) + dots + a_n x^n Q(x)
$
]
== Divisible
#definition(title: "Divisible")[
$M(x)$ divides $N(x)$ (we write $M(x) | N(x)$) if $N(x) = Q(x) dot M(x)$
$Q(x)$ is some polynomial.
We have: $deg(N) = deg(Q) + deg(M)$, so $deg(M) <= deg(N)$
So basically, you need to find a polynomial $Q(x)$ so that $Q(x) dot M(x) = N(x)$, then $M(x)$ divides $N(x)$
If $M(x) | N(x)$ and $N(x)|M(x)$, then they must have the same degree. And then $deg(Q)$ must have degree 0 and be a constant.
$exists alpha in RR: N(x) = alpha dot M(x)$
]
=== Common divisor
$D(x)$ is a common divisor of $M(x), N(x)$ if $D(x) | M(x) "and" D(x) | N(x)$
=== Greatest common divisor
#definition()[
$D_1(x)$ is _a_ greatest common divisor (gcd) of $M(x), N(x)$ if and only if $D$ is a common divisor and $D_1(x)$ also satisfies:
$ (D_1(x) | M(x) and D_1(x) | N(x)) => D_1(x) | D(x) $
If $D_1(x)$ is a greatest common divisor, then $D_1(x)$ times a constant is also a greatest common divisor
Suppose $D_2(x)$ is also a $"gcd"(M(x), N(x))$, then $D_2(x) | D_1(x)$ and $D_1(x) | D_2(x)$ so $D_2 = alpha D_1$
]
#note-box()[
There can be more than one greatest common divisor
]
Given $N(x), M(x)$, find a gcd.
#note-box(title: "For integers (repetition)")[
For integers: $n, m,$ find $"gcd"(n,m)$.
==== Euclid
$ n &= q_1 dot m + r_1, quad 0 <= r_1 < r_0 = m\
r_0 &= q_2 dot r_1 + r_2\
r_1 &= q_3 dot r_2 + r_3\
dots.v\
r_(k-3)&= q_(k-1) dot r_(k-2) + r_(k-1)\
r_(k-2)&= q_k dot r_(k-1) + r_k\
r_(k-1)&= q_(k+1) dot r_(k) + 0
$
$r_k$ is the greatest common divisor.
*Why is it a divisor*
It is the divisor because looking at the last line:
$r_k$ divides $r_(k-1), r_k$
We can go a line up: $r_(k-1)$ divides $r_(k-2), r_(k-1)$, but $r_k$ must also divide them.
Can go up a line again: $r_k$ divides $r_(k-3), r_(k-2)$ up until we get $r_k$ divides $n, m$
*Why is it the greatest common divisor*
$r_k$ can be written as a linear combination of $r_(k-2) "and" r_(k-1)$ which coefficients are integers.
You can go a line up and write $r_(k-1)$ as a linear combination, which you can input into $r_k$'s linear combination. Continue until you get:\
$
r_k = A dot N + B dot M
$
]
#definition(title: "GCD for polynomials")[
$deg(M) = m < n = deg(N)$
$
N(x) &= Q_1(x) dot M(x) + R_1(x), quad deg(R_1) < deg(M)\
M(x) &= Q_2(x) dot R_1(x) + R_2(x), quad deg(R_2) < deg(R_1)\
&dots.v\
R_(k-2)(x)&=Q_k (x) dot R_(k-1)(x)+R_k (x), quad deg(R_k) = 0\
R_(k-1)(x)&=Q_(k+1)(x) dot R_(k) (x)+0
$
$R_k (x) = A(x) dot N(x) + B(x) dot M(x)$
$A(x), B(x)$ are some polynomials.
$deg(R_k (x)) = deg(N(x)) - deg(M(x))$
]
#example()[
Find the greatest common divisor of
$
N(x) &= x^4 + x^3 - 2x^2 + 2x - 2 "and"\
M(x) &= x^2 + 2x -3
$
Divide:
$
underline(x^2+2x-3 |) x^4+3x^3-2x^2+2x-2 &underline(| x^2-x+3)\
underline(x^4 + 2x^3 -3x^2) &\
-x^3+x^2+2x-2&\
underline(-x^3-2x^2+3x)&\
3x^2-x-2&\
underline(3x^2+6x-9)&\
-7x+7
$
So:
$
N(x)=(x^2-x+3)M(x) + (-7x+7)
$
Now continue with the two new polynomials you found:
$
underline(-7x+7|) x^2+2x-3 &underline(|-1/7x-3/7)\
underline(x^2 - x)\
3x-3\
underline(3x-3)\
0
$
So:
$
M(x) = (-1/7 x - 3/7) dot (-7x+7) + 0
$
Now we're finished as we have 0. The greatest common divisor is $-7x+7$
We can write:
$
D(x)=-7x +7 = N(x) - (x^2-x+3) dot M(x)
$
To find $D_1(x)$ (a divisor of $D(x)$:
Remember: $D_1(x) = D(x) dot alpha$ where $alpha$ is a constant
$
D_1(x) = -x+1
$
#note-box()[
Both $D(x)$ and $D_1(x)$ are greatest common divisors of $N(x), M(x)$. as $D(x) = 1 dot D(x)$ (constant here is just $1$).
]
]
= Roots of polynomials
For the polynomial $a x^2 + b x + c$, the roots are: $(-b plus.minus sqrt(b^2 - 4 a c))/(2 a)$
Let's assume $"gcd"(N(x), M(x)) = D(x)$ then $alpha$ is a common root of $N(x), M(x) <=> alpha$ is a root in $D(x)$
$
N(x)=D(x) dot Q_1 (x)\
M(x)=D(x) dot Q_2 (x)
$
If $alpha$ is a root in $D(x)$, then it must also be a root in $M(x)$ and $N(x)$. The reason is that we can write $N, M$ as above
$
D(x) = A(x) N(x) + B(x) M(x)
$
$alpha$ is a root of $P(x) <=> (x- alpha)| P(x)$ which means $exists Q(x): P(x) = Q(x)(x-alpha) + beta$ where $beta$ is a constant
We can find $beta$ by calculating $P(alpha)$:
$
P(alpha) = Q(alpha)(alpha-alpha) + beta\
P(alpha) = Q(alpha)(0) + beta\
P(alpha) = beta
$
$x^2 +1= (x-i) dot (x+i)$

View File

@@ -0,0 +1,20 @@
#import "@local/dtu-template:0.5.1":*
#show: dtu-note.with(
course: "01017",
course-name: "Discrete Mathematics",
title: "Primes and the Eucledian algorithm",
date: datetime(day: 27, month: 11, year: 2025),
author: "Rasmus Rosendahl-Kaa (S255955)",
semester: "2025 Fall",
)
= Primes
#definition()[
$
a,b,c in ZZ, a in ZZ_+
$
If $a = b dot c$ then $a$ is _composite_ (sammensat), if not, then $a$ is a prime,
]

View File

@@ -0,0 +1,95 @@
\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\newtheorem{theorem}{Theorem}
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{corollary}[theorem]{Corollary}
\theoremstyle{definition}
\newtheorem{definition}[theorem]{Definition}
\title{Primes and the Euclidean Algorithm}
\date{02-10-2025}
\begin{document}
\maketitle
\section{Introduction}
Let $a, b \in \mathbb{Z}$. We say that $a$ \textbf{divides} $b$, written $a \mid b$, if there exists $c \in \mathbb{Z}$ such that $b = ac$.
\begin{definition}
A positive integer $p > 1$ is called \textbf{prime} if its only positive divisors are $1$ and $p$ itself.
\end{definition}
\begin{definition}
For integers $a$ and $b$, not both zero, the \textbf{greatest common divisor} $\gcd(a,b)$ is the largest positive integer that divides both $a$ and $b$.
\end{definition}
\section{The Euclidean Algorithm}
The Euclidean algorithm is an efficient method for computing the greatest common divisor of two integers.
\begin{theorem}[Division Algorithm]
Let $a, b \in \mathbb{Z}$ with $b > 0$. Then there exist unique integers $q$ and $r$ such that
\[
a = bq + r \quad \text{with} \quad 0 \leq r < b.
\]
Here $q$ is called the \textbf{quotient} and $r$ is called the \textbf{remainder}.
\end{theorem}
\begin{theorem}
If $a = bq + r$, then $\gcd(a,b) = \gcd(b,r)$.
\end{theorem}
\begin{proof}
Let $d = \gcd(a,b)$. Then $d \mid a$ and $d \mid b$. Since $r = a - bq$, we have $d \mid r$. Thus $d$ is a common divisor of $b$ and $r$, so $d \leq \gcd(b,r)$.
Conversely, let $d' = \gcd(b,r)$. Then $d' \mid b$ and $d' \mid r$. Since $a = bq + r$, we have $d' \mid a$. Thus $d'$ is a common divisor of $a$ and $b$, so $d' \leq \gcd(a,b) = d$.
Therefore $d = \gcd(b,r)$.
\end{proof}
\subsection{The Algorithm}
To compute $\gcd(a,b)$ where $a \geq b > 0$:
\begin{enumerate}
\item Apply the division algorithm repeatedly:
\begin{align*}
a &= bq_1 + r_1, \quad 0 \leq r_1 < b \\
b &= r_1 q_2 + r_2, \quad 0 \leq r_2 < r_1 \\
r_1 &= r_2 q_3 + r_3, \quad 0 \leq r_3 < r_2 \\
&\vdots \\
r_{n-2} &= r_{n-1} q_n + r_n, \quad 0 \leq r_n < r_{n-1} \\
r_{n-1} &= r_n q_{n+1} + 0
\end{align*}
\item The last non-zero remainder $r_n$ is $\gcd(a,b)$.
\end{enumerate}
\begin{theorem}[Bézout's Identity]
Let $a, b \in \mathbb{Z}$, not both zero, and let $d = \gcd(a,b)$. Then there exist integers $x$ and $y$ such that
\[
ax + by = d.
\]
\end{theorem}
\begin{proof}
Consider the set $S = \{ax + by : x, y \in \mathbb{Z} \text{ and } ax + by > 0\}$. This set is non-empty (contains $|a|$ or $|b|$) and bounded below by $1$, so by the well-ordering principle it has a smallest element, say $d' = ax_0 + by_0$.
We claim that $d' = \gcd(a,b)$. First we show that $d' \mid a$. By the division algorithm, write $a = d'q + r$ with $0 \leq r < d'$. Then
\[
r = a - d'q = a - (ax_0 + by_0)q = a(1 - x_0q) + b(-y_0q).
\]
If $r > 0$, then $r \in S$ and $r < d'$, contradicting the minimality of $d'$. Thus $r = 0$ and $d' \mid a$. Similarly, $d' \mid b$.
So $d'$ is a common divisor of $a$ and $b$, hence $d' \leq d = \gcd(a,b)$.
Conversely, since $d \mid a$ and $d \mid b$, we have $d \mid (ax_0 + by_0) = d'$. Thus $d \leq d'$.
Therefore $d = d'$, completing the proof.
\end{proof}
\end{document}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,88 @@
= Introduction
<introduction>
Let $a , b in bb(Z)$. We say that $a$ #strong[divides] $b$, written
$a divides b$, if there exists $c in bb(Z)$ such that $b = a c$.
#block[
#strong[Definition 1];. A positive integer $p > 1$ is called
#strong[prime] if its only positive divisors are $1$ and $p$ itself.
Hello
]
#block[
#strong[Definition 2];. For integers $a$ and $b$, not both zero, the
#strong[greatest common divisor] $gcd (a , b)$ is the largest positive
integer that divides both $a$ and $b$.
]
= The Euclidean Algorithm
<the-euclidean-algorithm>
The Euclidean algorithm is an efficient method for computing the
greatest common divisor of two integers.
#block[
#strong[Theorem 3] (Division Algorithm). #emph[Let $a , b in bb(Z)$ with
$b > 0$. Then there exist unique integers $q$ and $r$ such that
$ a = b q + r quad upright("with") quad 0 lt.eq r < b . $ Here $q$ is
called the #strong[quotient] and $r$ is called the #strong[remainder];.]
]
#block[
#strong[Theorem 4];. #emph[If $a = b q + r$, then
$gcd (a , b) = gcd (b , r)$.]
]
#block[
#emph[Proof.] Let $d = gcd (a , b)$. Then $d divides a$ and
$d divides b$. Since $r = a - b q$, we have $d divides r$. Thus $d$ is a
common divisor of $b$ and $r$, so $d lt.eq gcd (b , r)$.
Conversely, let $d' = gcd (b , r)$. Then $d' divides b$ and
$d' divides r$. Since $a = b q + r$, we have $d' divides a$. Thus $d'$
is a common divisor of $a$ and $b$, so $d' lt.eq gcd (a , b) = d$.
Therefore $d = gcd (b , r)$.~◻
]
== The Algorithm
<the-algorithm>
To compute $gcd (a , b)$ where $a gt.eq b > 0$:
+ Apply the division algorithm repeatedly:
$ a & = b q_1 + r_1 , quad 0 lt.eq r_1 < b\
b & = r_1 q_2 + r_2 , quad 0 lt.eq r_2 < r_1\
r_1 & = r_2 q_3 + r_3 , quad 0 lt.eq r_3 < r_2\
& dots.v\
r_(n - 2) & = r_(n - 1) q_n + r_n , quad 0 lt.eq r_n < r_(n - 1)\
r_(n - 1) & = r_n q_(n + 1) + 0 $
+ The last non-zero remainder $r_n$ is $gcd (a , b)$.
#block[
#strong[Theorem 5] (Bézouts Identity). #emph[Let $a , b in bb(Z)$, not
both zero, and let $d = gcd (a , b)$. Then there exist integers $x$ and
$y$ such that $ a x + b y = d . $]
]
#block[
#emph[Proof.] Consider the set
$S = { a x + b y : x , y in bb(Z) upright(" and ") a x + b y > 0 }$.
This set is non-empty (contains $lr(|a|)$ or $lr(|b|)$) and bounded
below by $1$, so by the well-ordering principle it has a smallest
element, say $d' = a x_0 + b y_0$.
We claim that $d' = gcd (a , b)$. First we show that $d' divides a$. By
the division algorithm, write $a = d' q + r$ with $0 lt.eq r < d'$. Then
$ r = a - d' q = a - (a x_0 + b y_0) q = a (1 - x_0 q) + b (- y_0 q) . $
If $r > 0$, then $r in S$ and $r < d'$, contradicting the minimality of
$d'$. Thus $r = 0$ and $d' divides a$. Similarly, $d' divides b$.
So $d'$ is a common divisor of $a$ and $b$, hence
$d' lt.eq d = gcd (a , b)$.
Conversely, since $d divides a$ and $d divides b$, we have
$d divides (a x_0 + b y_0) = d'$. Thus $d lt.eq d'$.
Therefore $d = d'$, completing the proof.~◻
]

File diff suppressed because it is too large Load Diff

View File

@@ -166,4 +166,4 @@ $ g compose f: A->C\ f compose g(a)=g(f(a)) $
Largest integer that is less than or equal to x
=== Ceiling function
Smallest integer that is greater than or equal to x
Smallest integer that is greater than or equal to x

View File

@@ -0,0 +1,6 @@
# Diskret Matematik gode programmer at have

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,57 @@
from sympy import *
def check_injective_surjective(func, var, domain, codomain):
x, y = symbols('x y')
# Check if the function is well-defined
outputs = {}
for val in domain:
output = func.subs(var, val)
if output in outputs:
# If the same output occurs for different inputs, it's not well-defined
if outputs[output] != val:
return "The function is not well-defined."
else:
outputs[output] = val
# Check injectivity
injective = True
for val1 in domain:
for val2 in domain:
if val1 != val2:
if func.subs(var, val1) == func.subs(var, val2):
injective = False
break
# Check surjectivity
surjective = True
for c_val in codomain:
try:
solutions = solve(Eq(func, c_val), var)
if not any(s in domain for s in solutions):
surjective = False
break
except:
surjective = False
break
# Results
if injective and surjective:
return "The function is bijective (both injective and surjective)."
elif injective:
return "The function is injective only."
elif surjective:
return "The function is surjective only."
else:
return "The function is neither injective nor surjective."
# Define the function and its domain/codomain
x = symbols('x')
func = Piecewise((2*x, x >= 0), (-2*x-1, x < 0))
domain = range(-20, 20) # For example, integers from -20 to 20
codomain = range(0, 40) # Adjusted codomain to include all possible outputs
result = check_injective_surjective(func, x, domain, codomain)
print(result)
print("please double check it yourself")

View File

@@ -0,0 +1,524 @@
import re
from itertools import permutations, product, chain, combinations
import math
import numpy as np
from sympy import mod_inverse
#import matplotlib.pyplot as plt
def is_prime(n):
if n <= 1:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
def primes_below(n):
primes = [i for i in range(2, n) if is_prime(i)]
return f"Number of primes below {n} is {len(primes)} and the list is {primes}"
def divide_with_remainder(a, b):
if b == 0:
return "Division by zero is undefined."
quotient = a // b
remainder = a % b
return f"The quotient of {a} divided by {b} is {quotient}, and the remainder is {remainder}."
# sent by jesper TA<3
def gcd(a, b):
rlist = [a, b]
qlist = []
while True:
r1 = rlist[-2]
r2 = rlist[-1]
if r2 == 0:
break
new_r = r1 % r2
qlist.append(r1 // r2)
rlist.append(new_r)
slist = [1, 0]
tlist = [0, 1]
for q in qlist:
s1 = slist[-2]
s2 = slist[-1]
t1 = tlist[-2]
t2 = tlist[-1]
slist.append(s1 - q * s2)
tlist.append(t1 - q * t2)
i = 0
print('i \t r_i \t r_i+1 \t q_i+1 \t r_i+2 \t s_i \t t_i')
for r1, r2, r3, q, s, t in zip(rlist, rlist[1:], rlist[2:], qlist, slist, tlist):
print(f'{i} \t {r1} \t {r2} \t {q} \t {r3} \t {s} \t {t}')
i += 1
print(f'\t\t\t\t\t {slist[-2]} \t {tlist[-2]}')
gcd_value = rlist[-2]
s_coeff = slist[-2]
t_coeff = tlist[-2]
result_string = f"GCD({a}, {b}) = {gcd_value}, with coefficients {s_coeff} and {t_coeff} such that {gcd_value} = ({s_coeff})*{a} + ({t_coeff})*{b}"
print(f'{result_string}')
#return gcd_value, s_coeff, t_coeff, result_string
def lcm(a, b):
def gcd(a, b):
while b:
a, b = b, a % b
return a
gcd_value = gcd(a, b)
lcm_value = abs(a * b) // gcd_value
result_string = (
f"LCM({a}, {b}) = {lcm_value}, Here, GCD({a}, {b}) = {gcd_value}."
)
print(result_string)
#return lcm_value, result_string
# Sent by Alexander Piepgrass <3
def _min_gcd_congruences(a,b):
rlist = [a,b]
qlist = []
while True:
r1 = rlist[-2]
r2 = rlist[-1]
if r2==0:
break
new_r = r1%r2
qlist.append(r1//r2)
rlist.append(new_r)
slist = [1,0]
tlist = [0,1]
for q in qlist:
s1 = slist[-2]
s2 = slist[-1]
t1 = tlist[-2]
t2 = tlist[-1]
slist.append(s1-q*s2)
tlist.append(t1-q*t2)
i = 0
return rlist[-2], slist[-2], tlist[-2]
# sent by alexander piepgrass <3
def congruences_system_solver(system):
m=1
for cong in system:
m*=cong[1]
M_list = []
for cong in system:
M_list.append(m//cong[1])
y_list=[]
for i in range(len(M_list)):
r,s,t= _min_gcd_congruences(M_list[i],system[i][1])
y_list.append(s)
x=0
for i in range(len(M_list)):
x+=system[i][0]*M_list[i]*y_list[i]
print(f'all solutions are {x % m} + {m}k')
return x % m, m, M_list, y_list
def some_congruences_system_solver(system):
normalized_system = []
for b, a, n in system:
g = math.gcd(b, n)
if a % g != 0:
raise ValueError(f"No solution exists for {b}*x ≡ {a} (mod {n})")
# Reduce b*x ≡ a (mod n) to x ≡ c (mod m)
b = b // g
a = a // g
n = n // g
b_inv = mod_inverse(b, n)
c = (b_inv * a) % n
normalized_system.append((c, n))
# Solve the normalized system of congruences
m = 1
for _, n in normalized_system:
m *= n
M_list = []
for _, n in normalized_system:
M_list.append(m // n)
y_list = []
for i in range(len(M_list)):
r, s, t = _min_gcd_congruences(M_list[i], normalized_system[i][1])
y_list.append(s)
x = 0
for i in range(len(M_list)):
x += normalized_system[i][0] * M_list[i] * y_list[i]
print(f'All solutions are {x % m} + {m}k')
return x % m, m, M_list, y_list
def solve_congruence_general(a, c, m):
"""
Solves the congruence ax ≡ c (mod m).
Returns a general solution in the form x ≡ x0 + k*b (mod m),
or 'No solution' if no solution exists.
"""
from math import gcd
# Step 1: Compute gcd(a, m)
g = gcd(a, m)
# Step 2: Check if a solution exists
if c % g != 0:
return "No solution"
# Step 3: Simplify the congruence
a, c, m = a // g, c // g, m // g
# Step 4: Find the modular inverse of a modulo m
def extended_gcd(a, b):
"""Helper function to compute the extended GCD."""
if b == 0:
return a, 1, 0
g, x, y = extended_gcd(b, a % b)
return g, y, x - (a // b) * y
g, x, _ = extended_gcd(a, m)
if g != 1: # Sanity check for modular inverse
return "No solution"
x = (x % m + m) % m # Ensure x is positive
x0 = (c * x) % m # Particular solution
# General solution is x ≡ x0 + k * m
return f"x ≡ {x0} + k * {m}"
def explain_quantifiers(logic_string):
"""
Converts a LaTeX-style logical string into a human-readable explanation.
Supports various quantifiers, logical types, and biimplication.
"""
# Normalize LaTeX equivalents to symbols
latex_to_symbol_map = {
r"\\forall": "",
r"\\exists": "",
r"\\in": "",
r"\\notin": "",
r"\\mathbb\{R\}": "",
r"\\neq": "",
r"\\rightarrow": "",
r"\\leftrightarrow": "",
r"\\lor": "",
r"\\land": "",
r"\\neg": "¬",
r"\\leq": "",
r"\\geq": "",
r"\\subseteq": "",
r"\\supseteq": "",
r"\\subset": "",
r"\\supset": "",
r"\\emptyset": "",
}
for latex, symbol in latex_to_symbol_map.items():
logic_string = re.sub(latex, symbol, logic_string)
# Dictionary to map symbols to words
symbol_map = {
"": "For all",
"": "There exists",
"": "in",
"": "not in",
"": "the set of all real numbers",
"": "implies that",
"": "if and only if",
"": "or",
"": "and",
"¬": "not",
"=": "is equal to",
"": "is not equal to",
"<": "is less than",
">": "is greater than",
"": "is less than or equal to",
"": "is greater than or equal to",
"": "is a subset of",
"": "is a superset of",
"": "is a proper subset of",
"": "is a proper superset of",
"": "the empty set",
}
# Replace symbols with words
for symbol, word in symbol_map.items():
logic_string = logic_string.replace(symbol, word)
# Custom processing for specific patterns
# Match quantifiers and variables
logic_string = re.sub(r"For all (\w) in (.*?),", r"Given any \1 in \2,", logic_string)
logic_string = re.sub(r"There exists (\w) in (.*?),", r"There is a \1 in \2,", logic_string)
# Handle logical groupings with parentheses
logic_string = re.sub(r"\((.*?)\)", r"where \1", logic_string)
# Ensure precise formatting
logic_string = logic_string.strip()
return logic_string
def get_permutations(input_string):
"""
Returns all permutations of the given string.
"""
# Generate permutations using itertools.permutations
perm = permutations(input_string)
# Convert to a list of strings
perm_list = [''.join(p) for p in perm]
return perm_list
def get_r_permutations(input_string, r):
"""
Returns all r-permutations of the given string.
Parameters:
input_string (str): The string to generate permutations from.
r (int): The length of the permutations.
Returns:
list: A list of all r-permutations as strings.
"""
# Generate r-permutations using itertools.permutations
r_perm = permutations(input_string, r)
# Convert to a list of strings
r_perm_list = [''.join(p) for p in r_perm]
return r_perm_list
def get_binary_strings(n, as_strings=False):
# Generate all possible bit strings of length n
bit_combinations = product([0, 1], repeat=n)
if as_strings:
# Join bits as strings
return ["".join(map(str, bits)) for bits in bit_combinations]
else:
# Return as lists of integers
return [list(bits) for bits in bit_combinations]
def get_combinations(input_string):
"""
Returns all combinations of the given string (for all lengths).
Parameters:
input_string (str): The string to generate combinations from.
Returns:
list: A list of all combinations as strings.
"""
comb_list = []
for r in range(1, len(input_string) + 1):
comb_list.extend([''.join(c) for c in combinations(input_string, r)])
return comb_list
def get_r_combinations(input_string, r):
"""
Returns all r-combinations of the given string.
Parameters:
input_string (str): The string to generate combinations from.
r (int): The length of the combinations.
Returns:
list: A list of all r-combinations as strings.
"""
r_comb = combinations(input_string, r)
r_comb_list = [''.join(c) for c in r_comb]
return r_comb_list
def calculate_number_of_derangements(n):
"""
Calculate the number of derangements (Dn) for n elements
using the formula:
Dn = n! * (1 - 1/1! + 1/2! - 1/3! + ... + (-1)^n/n!)
"""
result = 0
for i in range(n + 1):
result += ((-1)**i) / math.factorial(i)
return round(math.factorial(n) * result)
def is_derangement(original, perm):
"""
Checks if a permutation is a derangement of the original string.
"""
return all(original[i] != perm[i] for i in range(len(original)))
def get_derangements(input_string):
"""
Returns all derangements of a given string as an array of strings.
"""
original = list(input_string)
all_permutations = permutations(original)
derangements = ["".join(perm) for perm in all_permutations if is_derangement(original, perm)]
return derangements
def multiplicative_inverse(n, mod):
def gcd_extended(a, b):
if a == 0:
return b, 0, 1
gcd, x1, y1 = gcd_extended(b % a, a)
x = y1 - (b // a) * x1
y = x1
return gcd, x, y
gcd, x, _ = gcd_extended(n, mod)
if gcd != 1: # If gcd of n and mod is not 1, inverse doesn't exist
return "Does not exist"
else:
# Make the result positive
return x % mod
def minimum_selections_for_sum(numbers, target_sum):
selected_numbers = set()
for num in numbers:
if target_sum - num in selected_numbers:
# Pair found
return len(selected_numbers) + 1
selected_numbers.add(num)
# No pair found within the set
return None
def is_transitive(R):
for a, b in R:
for c, d in R:
if b == c and ((a, d) not in R):
return False
return True
def is_reflexive(S, R):
newSet = {(a, b) for a in S for b in S if a == b}
if R >= newSet:
return True
return False
def is_symmetric(R):
if all(tup[::-1] in R for tup in R):
return True
return False
def is_antisymmetric(R):
return all((y, x) not in R for x, y in R if x != y)
def is_equivalence_relation(S, R):
return is_symmetric(R) and is_reflexive(S, R) and is_transitive(R)
def is_partial_order(S, R):
"""Check if the relation R on set S is a partial order."""
return is_antisymmetric(R) and is_reflexive(S, R) and is_transitive(R)
def check_func(func_to_check, domain, codomain):
"""
Check if a function is "well-defined" over a given domain and codomain constraint.
Parameters:
func_to_check: callable
The function to check. It should take one argument.
domain: list
A list of values to test the function with.
codomain: callable
A callable that takes the output of the function and returns True if it satisfies the codomain constraint.
Returns:
bool
True if the function is well-defined over the domain and codomain, otherwise False.
"""
well_defined = True
for x in domain:
try:
# Evaluate the function
output = func_to_check(x)
# Check the codomain constraint
if not codomain(output):
print(f"Input {x}: Output {output} is INVALID.")
well_defined = False
except Exception as e:
# Catch errors in evaluation
print(f"Input {x}: Error occurred - {str(e)}.")
well_defined = False
if well_defined:
print("The function is well-defined over the given domain.")
else:
print("The function is NOT well-defined over the given domain.")
return well_defined
def plot_function(functions: list, plot_range: list):
"""Takes a function and plots the graph using the plot_range.
The plot_rage should be a list containing two elements: the minimum value to plot, up to the max value.
function should be a list of functions to be drawn. The functions in the list should take one parameter and return a value.
"""
x_values = range(plot_range[0],plot_range[1])
for func in functions:
y_points = []
x_points = []
for i in range(plot_range[0], plot_range[1]):
y_points.append(func(i))
x_points.append(i)
plt.plot(x_points, y_points, label=func.__name__)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Function Plots')
plt.legend()
plt.grid(True)
plt.show()
print(lcm(82,21))
print(lcm(42,123))