Common mathematical knowledge

Source: Internet
Author: User
Tags decimal to binary greatest common divisor
Introduction
I have seen a number of competitors complain that they are unfairly
Disadvantaged because extends TopCoder problems are too mathematical.
Personally, I love mathematics and thus I am biased in this issue.
Nevertheless, I stronugly believe that problems shoshould contain at least
Some math, because mathematics and computer science often go hand in
Hand. It is hard to imagine a world where these two fields cocould exist
Without any interaction with each other. These days, a great deal
Applied mathematics is saved med on computers such as solving large
Systems of equations and approximating solutions to differential
Equations for which no closed formula exists. Mathematics is widely
Used in computer science research, as well as being heavily applied
Graph algorithms and areas of computer vision.

This article discusses the theory and practical application
To some of the more common mathematical constructs. The topics covered
Are: primes, GCD, basic geometry, bases, fractions and complex numbers.

Primes

A number is prime if it is only divisible by 1 and itself. So
Example 2, 3, 5, 79,311 and 1931 are all prime, while 21 is not prime
Because it is divisible by 3 and 7. To find if a number n is prime we
Cocould simply check if it divides any numbers below it. We can use
Modulus (%) operator to check for divisibility:

for (int i=2; i<n; i++)
if (n%i==0) return false;
return true;

We can make this code run faster by noticing that we only need
Check divisibility for values of I that are less or equal to the square
Root of n (call this m). If n divides a number that is greater than m
Then the result of that division will be some number less than m and
Thus n will also divide a number less or equal to m. Another
Optimization is to realize that there are no even primes greater
2. Once we 've checked that n is not even we can safely increment
Value of I by 2. We can now write the final method for checking whether
A number is prime:

public boolean isPrime (int n)
{
if (n<=1) return false;
if (n==2) return true;
if (n%2==0) return false;
int m=Math.sqrt(n);

for (int i=3; i<=m; i+=2)
if (n%i==0)
return false;

return true;
}

Now suppose we wanted to find all the primes from 1 to 100000,
Then we wowould have to call the above method 100000 times. This wocould be
Very inefficient since we wocould be repeating the same calculations over
And over again. In this situation it is best to use a method known
The Sieve of Eratosthenes. The Sieve of Eratosthenes will generate all
The primes from 2 to a given number n. It begins by assuming that all
Numbers are prime. It then takes the first prime number and removes all
Of its multiples. It then applies the same method to the next prime
Number. This is continued until all numbers have been processed.
Example, consider finding primes in the range 2 to 20. We begin
Writing all the numbers down:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

2 is the first prime. We now cross out all of its multiples, ie every second number:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

The next non-crossed out number is 3 and thus it is the second
Prime. We now cross out all the multiples of 3, ie every third number
From 3:

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

All the remaining numbers are prime and we can safely terminate the algorithm. Below is the code for the sieve:

public boolean[] sieve(int n)
{
boolean[] prime=new boolean[n+1];
Arrays.fill(prime,true);
prime[0]=false;
prime[1]=false;
int m=Math.sqrt(n);

for (int i=2; i<=m; i++)
if (prime[i])
for (int k=i*i; k<=n; k+=i)
prime[k]=false;

return prime;
}

In the above method, we create a boolean array prime which stores
The primality of each number less of equal than n. If prime [I] is true
Then number I is prime. The outer loop finds the next prime while
Inner loop removes all the multiples of the current prime.


GCD
The greatest common divisor
(GCD) of two numbers a and B is the greatest number that divides evenly
Into both a and B. Naively we cocould start from the smallest of the two
Numbers and work our way downwards until we find a number that divides
Into both of them:

for (int i=Math.min(a,b); i>=1; i--)
if (a%i==0 && b%i==0)
return i;

Although this method is fast enough for most applications, there
Is a faster method called Euclid's algorithm. Euclid's algorithm
Iterates over the two numbers until a remainder of 0 is found.
Example, suppose we want to find the GCD of 2336 and 1314. We begin
Expressing the larger number (2336) in terms of the smaller number
(1314) plus a remainder:

2336 = 1314 x 1 + 1022

We now do the same with 1314 and 1022:

1314 = 1022 x 1 + 292

We continue this process until we reach a remainder of 0:

1022 = 292 x 3 + 146
292 = 146 x 2 + 0

The last non-zero remainder is the GCD. So the GCD of 2336 and
1314 is 146. This algorithm can be easily coded as a recursive
Function:

//assume that a and b cannot both be 0
public int GCD(int a, int b)
{
if (b==0) return a;
return GCD(b,a%b);
}

Using this algorithm we can find the lowest common multiple (LCM)
Of two numbers. For example the LCM of 6 and 9 is 18 since 18 is
Smallest number that divides both 6 and 9. Here is the code for the LCM
Method:

public int LCM(int a, int b)
{
return b*a/GCD(a,b);
}

As a final note, Euclid's algorithm can be used to solve linear
Diophantine equations. These equations have integer coefficients and
Are of the form:

ax + by = c


Geometry
Occasionally problems ask
Us to find the intersection of rectangles. There are a number of ways
To represent a rectangle. For the standard Cartesian plane, a common
Method is to store the coordinates of the bottom-left and top-right
Corners.

Suppose we have two rectangles R1 and R2. Let (x1, y1) be
Location of the bottom-left corner of R1 and (x2, y2) be the location
Of its top-right corner. Similarly, let (x3, y3) and (x4, y4) be
Respective corner locations for R2. The intersection of R1 and R2 will
Be a rectangle R3 whose bottom-left corner is at (max (x1, x3), max (y1,
Y3) and top-right corner at (min (x2, x4), min (y2, y4). If max (x1, x3)
> Min (x2, x4) or max (y1, y3)> min (y2, y4) then R3 does not
Exist, ie R1 and R2 do not intersect. This method can be extended
Intersection in more than 2 dimensions as seen in CuboidJoin (SRM 191,
Div 2 Hard ).

Often we have to deal with polygons whose vertices have
Integer coordinates. Such polygons are called lattice polygons. In his
Tutorial on Geometry Concepts, lbackstrom presents a neat way
Finding the area of a lattice polygon given its vertices. Now, suppose
We do not know the exact position of the vertices and instead we are
Given two values:

B = number of lattice points on the boundary of the polygon

I = number of lattice points in the interior of the polygon

Amazingly, the area of this polygon is then given:

Area = B/2 + I - 1

The above formula is called Pick's Theorem due to Georg Alexander
Pick (1859-1943). In order to show that Pick's theorem holds for all
Lattice polygons we have to prove it in 4 separate parts. In the first
Part we show that the theorem holds for any lattice rectangle (
Sides parallel to axis). Since a right-angled triangle is simply half
Of a rectangle it is not too difficult to show that the theorem also
Holds for any right-angled triangle (with sides parallel to axis).
Next step is to consider a general triangle, which can be represented
As a rectangle with some right-angled triangles cut out from its
Corners. Finally, we can show that if the theorem holds for any two
Lattice polygons sharing a common side then it will also hold for
Lattice polygon, formed by removing the common side. Combining
Previous result with the fact that every simple polygon is a union
Triangles gives us the final version of Pick's Theorem. Pick's theorem
Is useful when we need to find the number of lattice points inside
Large polygon.

Another formula worth remembering is Euler's Formula for polygonal
Nets. A polygonal net is a simple polygon divided into smaller
Polygons. The smaller polygons are called faces, the sides of the faces
Are called edges and the vertices of the faces are called vertices.
Euler's Formula then states:

V - E + F = 2, where

V = number of vertices
E = number of edges
F = number of faces

For example, consider a square with both diagonals drawn. We have
V = 5, E = 8 and F = 5 (the outside of the square is also a face) and
So V-E + F = 2.

We can use induction to show that Euler's formula works. We
Must begin the induction with V = 2, since every vertex has to be on
Least one edge. If V = 2 then there is only one type of polygonal net
Possible. It has two vertices connected by E number of edges. This
Polygonal net has E faces (E-1 "in the middle" and 1 "outside"). So V
-E + F = 2-E + E = 2. We now assume that V-E + F = 2 is true
All 2 <= V <= n. Let V = n + 1. Choose any vertex w at random. Now
Suppose w is joined to the rest of the net by G edges. If we remove w
And all these edges, we have a net with n vertices, E-G edges and F-
G + 1 faces. From our assumption, we have:

(n) - (E - G) + (F - G + 1) = 2
thus (n+1) - E + F = 2

Since V = n + 1, we have V-E + F = 2. Hence by the principal of mathematical induction we have proven Euler's formula.


Bases
A very common problem faced
By TopCoder competitors during contests involves converting to and from
Binary and decimal representations (amongst others ).

So what does the base of the number actually mean? We will
Begin by working in the standard (decimal) base. Consider the decimal
Number 4325. 4325 stands for 5 + 2x10 + 3x10x10 + 4x10x10 x
10. Notice that the "value" of each consequent digit increases by
Factor of 10 as we go from right to left.
Binary numbers work in a similar way. They are composed solely from 0
And 1 and the "value" of each digit increases by a factor of 2 as we go
From right to left. For example, 1011 in binary stands for 1 + 1x2 +
0x2x2 + 1x2x2 = 1 + 2 + 8 = 11 in decimal. We have just
Converted a binary number to a decimal. The same applies to other
Bases. Here is code which converts a number n in base B
(2 <= B <= 10) to a decimal number:

public int toDecimal(int n, int b)
{
int result=0;
int multiplier=1;

while(n>0)
{
result+=n%10*multiplier;
multiplier*=b;
n/=10;
}

return result;
}

Java users will be happy to know that the above can be also written:

return Integer.parseInt(""+n,b);

To convert from a decimal to a binary is just as easy. Suppose we
Wanted to convert 43 in decimal to binary. At each step of the method
We divide 43 by 2 and memorize the remainder. The final list
Remainders is the required binary representation:

43/2 = 21 + remainder 1
21/2 = 10 + remainder 1
10/2 = 5 + remainder 0
5/2 = 2 + remainder 1
2/2 = 1 + remainder 0
1/2 = 0 + remainder 1

So 43 in decimal is 101011 in binary. By swapping all occurrences
Of 10 with B in our previous method we create a function which converts
From a decimal number n to a number in base B (2 <= B <= 10 ):

public int fromDecimal(int n, int b)
{
int result=0;
int multiplier=1;

while(n>0)
{
result+=n%b*multiplier;
multiplier*=10;
n/=b;
}

return result;
}

If the base B is above 10 then we must use non-numeric characters
To represent digits that have a value of 10 and more. We can let 'A'
Stand for 10, 'B' stand for 11 and so on. The following code will
Convert from a decimal to any base (up to base 20 ):

public String fromDecimal2(int n, int b)
{
String chars="0123456789ABCDEFGHIJ";
String result="";

while(n>0)
{
result=chars.charAt(n%b) + result;
n/=b;
}

return result;
}

In Java there are some useful shortcuts when converting from
Decimal to other common representations, such as binary (base 2), octal
(Base 8) and hexadecimal (base 16 ):

Integer.toBinaryString(n);
Integer.toOctalString(n);
Integer.toHexString(n);


Fractions and Complex Numbers
Fractional
Numbers can be seen in your problems. Perhaps the most difficult aspect
Of dealing with fractions is finding the right way of representing
Them. Although it is possible to create a fractions class containing
The required attributes and methods, for most purposes it is sufficient
To represent fractions as 2-element arrays (pairs). The idea is that we
Store the numerator in the first element and the denominator in
Second element. We will begin with multiplication of two fractions
And B:

public int[] multiplyFractions(int[] a, int[] b)
{
int[] c={a[0]*b[0], a[1]*b[1]};
return c;
}

Adding fractions is slightly more complicated, since only
Fractions with the same denominator can be added together. First of all
We must find the common denominator of the two fractions and then use
Multiplication to transform the fractions such that they both have
Common denominator as their denominator. The common denominator is
Number which can divide both denominators and is simply the LCM
(Defined earlier) of the two denominators. For example lets add 4/9 and
1/6. LCM of 9 and 6 is 18. Thus to transform the first fraction we need
To multiply it by 2/2 and multiply the second one by 3/3:

4/9 + 1/6 = (4*2)/(9 * 2) + (1 * 3)/(6 * 3) =  8/18 +  3/18

Once both fractions have the same denominator, we simply add
Numerators to get the final answer of 11/18. Subtraction is very
Similar, since t we subtract at the last step:

4/9 - 1/6 =  8/18 -  3/18 =  5/18

Here is the code to add two fractions:

public int[] addFractions(int[] a, int[] b)
{
int denom=LCM(a[1],b[1]);
int[] c={denom/a[1]*a[0] + denom/b[1]*b[0], denom};
return c;
}

Finally it is useful to know how to reduce a fraction to its
Simplest form. The simplest form of a fraction occurs when the GCD
The numerator and denominator is equal to 1. We do this like so:

public void reduceFraction(int[] a)
{
int b=GCD(a[0],a[1]);
a[0]/=b;
a[1]/=b;
}

Using a similar approach we can represent other special numbers,
Such as complex numbers. In general, a complex number is a number
The form a + ib, where a and B are reals and I is the square root
-1. For example, to add two complex numbers m = a + ib and n = c + id
We simply group likewise terms:

m + n
= (a + ib) + (c + id)
= (a + c) + i(b + d)

Multiplying two complex numbers is the same as multiplying two real numbers, please t we must use the fact that I ^ 2 =-1:

m * n
= (a + ib) * (c + id)
= ac + iad + ibc + (i^2)bd
= (ac - bd) + i(ad + bc)

By storing the real part in the first element and the complex
Part in the second element of the 2-element array we can write code
That performs the above multiplication:

public int[] multiplyComplex(int[] m, int[] n)
{
int[] prod = {m[0]*n[0] - m[1]*n[1], m[0]*n[1] + m[1]*n[0]};
return prod;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.