Euler's Sieve - പ്രൈം നമ്പറിനെക്കുറിച്ച് തന്നെ

കഴിഞ്ഞ പോസ്റ്റില്‍ R. ഇട്ട കമന്റില്‍ നിന്നാണ്‌ പ്രൈം നമ്പറുകള്‍ കണ്ടു പിടിക്കാനുള്ളുഅ ഇറാത്തോസ്തനീസിന്റെ അല്‍ഗോരിതത്തിലെത്തിച്ചേര്‍ന്നത്.
അതിന്റെ സി ഇമ്പ്ലിമെന്റേഷന്‍ വിക്കി പേജിന്റെ അവസാനം External Links ഇല്‍ കൊടുത്തിട്ടുണ്ട്.
അതില്‍ ഫ്ലാഗുകളുടെ അയ്യരുകളിയാണ്‌. ഫ്ലാഗില്ലാതെ എങ്ങിനെ ചെയ്യാം എന്നാണല്ലോ നമ്മുടെ ലക്ഷ്യം തന്നെ.

എന്നാല്‍ പിന്നെ ഒന്നു ശ്രമിച്ചു നോക്കാം എന്നു കരുതി. ഇറാത്തോസ്തനീസിന്റെ അല്‍ഗോരിതത്തിലെത്തിന്റെ ഒന്നു കൂടെ മെച്ചപ്പെടുത്തിയ യുളേഴ്സ് അല്‍ഗോരിതം പരീക്ഷിക്കുന്നതിലാവും രസം. (അല്‍ഗോരിതം വിക്കിയില്‍ നോക്കുക).

ലിസ്റ്റ് ഉപയോഗിച്ച് ചെയ്യുന്നതാണ്‌ രസം. സി യില്‍ ലിസ്റ്റ് ഉപയോഗിക്കന്നത് ആലോചിക്കാനേ വയ്യ. അത് കൊണ്ട് ഒരു ഒബ്ജക്റ്റ് ഓറിയന്റഡ് ലാംഗ്വേജ് ആണ്‌ നല്ലത്. സിഷാര്‍പ്പാവട്ടെ.

സിഷാര്‍പ്പിനു വേണ്ടി അല്‍ഗോരിതം ഇങ്ങനെ മാറ്റിയെഴുതി


A. രണ്ട് മുതല്‍ പരമാവധി സംഖ്യ വരെ ഒരു ലിസ്റ്റിനകത്ത് സ്റ്റോര്‍ ചെയ്യുക. ഇതേ സംഖ്യകള്‍ ഒരു നിരയിലും (Array) സൂക്ഷിക്കുക. (ലിസ്റ്റിനു പേരു intList എന്നും നിരക്കു പേരു intArray എന്നും കൊടുക്കാം )

B.

1. intArray യിലെ ഏറ്റവും ഇടതു വശത്തെ സംഖ്യ മുതല്‍ തുടങ്ങുക. ഇടത് വശത്തെ ആദ്യസംഖ്യ പ്രൈം ആയിരിക്കും. അതിനെ പ്രിന്റ് ചെയ്ത ശേഷം അത് RemoveMultiples എന്ന method നെ വിളിക്കുക.

2.RemoveMultiples ചെയ്യുക എന്താണെന്ന് വെച്ചാല്‍ intArray നിരയിലെ ആദ്യസംഖ്യ എപ്പോഴും പ്രൈം ആയിരിക്കും. ആ സംഖ്യ ഉപയോഗിച്ച് നിരയിലെ മറ്റെല്ലാ സംഖ്യകളെയും ഗുണിക്കുക. ഗുണനഫലമായി കിട്ടുന്ന സംഖ്യകളെ ലിസ്റ്റില്‍ നിന്നും നീക്കം ചെയ്യുക.

3.പുതിയതായി കിട്ടിയ ലിസ്റ്റിനെ വീണ്ടും intArray യിലേക്ക് കോപ്പി ചെയ്യുക. കോപ്പി ചെയ്യുമ്പോള്‍ ഇത് വരെ പ്രിന്റ് ചെയ്ത പ്രൈം നമ്പറുകള്‍ ആവശ്യമില്ല. (അപ്പോഴും intArray യിലെ ഏറ്റവും ഇടത് വശത്തെ നമ്പര്‍ പ്രൈം തന്നെയായിരിക്കും


C. B1 മുതല്‍ B3 വരെ ആവര്‍ത്തിക്കുക - ലിസ്റ്റിലെ അവസാനസംഖ്യ വരെ പരിശോധിക്കപ്പെടും വരെ.

B1 എന്ന സ്റ്റെപ്പില്‍ സംഖ്യ പ്രിന്റ് ചെയ്യുന്നത് ശ്രദ്ധിച്ചല്ലോ അത് കൊണ്ട് കോഡ് ഓടിക്കഴിയുമ്പോഴേക്കും പ്രൈം നമ്പറുകള്‍ എല്ലാം പ്രിന്റ് ചെയ്ത് കഴിഞ്ഞിരിക്കും. കൂടാതെ ഏറ്റവും അവസാനം ലിസ്റ്റില്‍ അവശേഷിക്കുന്നത് പ്രൈം നമ്പറുകള്‍ മാത്രം ആയിരിക്കുകയും ചെയ്യും.

കോഡ് താഴെ കൊടുത്തിരിക്കുന്നു.
calvin@Singularity:~/programming/csharp$ gedit PrintPrime.cs


using System;
using System.Collections;

public class IntegerList{


private ArrayList intList;
private int[] intArray;
private int lastIndex;

public IntegerList (int iMax) {
//constructor - will populate list and the array with integers starting from 2 to iMax
int i;
intList = new ArrayList();
intArray = new int[iMax];
for (i=2;i<=iMax;i++) {
intList.Add(i);
intArray[i-2] = i;
}
lastIndex = intList.Count;
}

protected void CopyList(int currIndex){
//copy the items from list to array excluding the items from left which has already got printed.
int i=0;
for(i=0;(i+currIndex)<intList.Count;i++){
intArray[i] = (int) intList[(i+currIndex)];
}
intArray[i+1] = 0;
}


protected void RemoveMultiples(int iMax ){
//the array will contain the all items from list minus the numbers that have already identified as prime
int iPrime = intArray[0];
int i =0;
for(i=0; intArray[i]*iPrime<=iMax ; i++){
Console.WriteLine("Removing {0}, currprime {1}", intArray[i]*iPrime, iPrime);
intList.Remove(intArray[i]*iPrime);

}

lastIndex=intList.Count;
}


public void FindPrime(int iMax){
int currIndex = 0;
while (currIndex < lastIndex){
Console.WriteLine("{0} is a Prime Number", intList[currIndex]);
RemoveMultiples(iMax);
currIndex++;
CopyList(currIndex);



}
}

public void PrintAgain(){
Console.WriteLine("\n Printiing the content if intList");
Console.WriteLine("===================================");
foreach(int intPrime in intList)
{
Console.WriteLine("{0} is a prime number",intPrime);
}

}

}


class PrintPrime
{
// Main begins program execution.
public static int Main(String[] args)
{

try {
int iMax = int.Parse(args[0]);
// Write to console
Console.WriteLine("Hello All");

IntegerList il = new IntegerList(iMax);
Console.WriteLine("List of prime numbers that are < {0} \n", args[0]);
il.FindPrime(iMax);
il.PrintAgain();
}
catch (System.IndexOutOfRangeException){
Console.WriteLine("Argument 'Maximum Number' is missing'");

}
finally{
Console.WriteLine("Good Bye");
}

return 0;
}
}

കോഡിലെ ചില പ്രത്യേകതകള്‍ എന്താണ്‌ എന്ന് വെച്ചാല്‍
ക. പരമാവധി സംഖ്യ മുന്‍‌നിശ്ചയിച്ച് ഹാര്‍ഡ്-കോഡ് ചെയ്യുന്നതിനു പകരം കമാന്‍ഡ് ലൈന്‍ ആര്‍ഗ്യുമെന്റ് ആയി പാസ് ചെയ്യുന്നു.
ഖ. എല്ലാം പ്രിന്റ് ചെ‌‌യ്ത ശേഷം, ലിസ്റ്റിലെ സംഖ്യകള്‍ ഒന്നു കൂടെ പ്രിന്റ് ചെയ്യുന്നു.
ഗ. RemoveMultiples സ്റ്റെപ്പില്‍ ഓരോ തവണയും ഏതെല്ലാം സംഖ്യ ഒഴിവാക്കുന്നു എന്ന് പ്രിന്റ് ചെയ്യുന്നു (വെറുതെ കാണാന്‍ വേണ്ടി).
ഘ. പ്രോഗ്രാം റണ്‍ ചെയ്യുന്ന മഹാന്‍ അഥവാ പരമാവധി സംഖ്യ കമാന്‍ഡ് ലൈന്‍ ആര്‍ഗ്യുമെന്റായി കൊടുക്കാന്‍ മറന്നാല്‍ ഒരു യൂസര്‍ ഫ്രണ്ട്ലി എറര്‍ മെസ്സേജ് കാണിക്കും (try-catch-finally ഉപയോഗിച്ച്).


Compile:
യൂണിക്സില്‍ ഇങ്ങനെ Compile ചെയ്യാവുന്നതാണ്‌. (CSharp compiler ആയ cscc ഇന്‍സ്റ്റാള്‍ ചെയ്തിരിക്കണം)
calvin@Singularity:~/programming/csharp$ cscc PrintPrime.cs

Run ചെയ്യാന്‍ (ഉദാഹരണം ആയി 120 വരെ)

calvin@Singularity:~/programming/csharp$ ./a.out 120


Output:

Hello All
List of prime numbers that are 2 is a Prime Number
Removing 4, currprime 2
Removing 6, currprime 2
Removing 8, currprime 2
Removing 10, currprime 2
Removing 12, currprime 2
Removing 14, currprime 2
Removing 16, currprime 2
Removing 18, currprime 2
Removing 20, currprime 2
Removing 22, currprime 2
Removing 24, currprime 2
Removing 26, currprime 2
Removing 28, currprime 2
Removing 30, currprime 2
Removing 32, currprime 2
Removing 34, currprime 2
Removing 36, currprime 2
Removing 38, currprime 2
Removing 40, currprime 2
Removing 42, currprime 2
Removing 44, currprime 2
Removing 46, currprime 2
Removing 48, currprime 2
Removing 50, currprime 2
Removing 52, currprime 2
Removing 54, currprime 2
Removing 56, currprime 2
Removing 58, currprime 2
Removing 60, currprime 2
Removing 62, currprime 2
Removing 64, currprime 2
Removing 66, currprime 2
Removing 68, currprime 2
Removing 70, currprime 2
Removing 72, currprime 2
Removing 74, currprime 2
Removing 76, currprime 2
Removing 78, currprime 2
Removing 80, currprime 2
Removing 82, currprime 2
Removing 84, currprime 2
Removing 86, currprime 2
Removing 88, currprime 2
Removing 90, currprime 2
Removing 92, currprime 2
Removing 94, currprime 2
Removing 96, currprime 2
Removing 98, currprime 2
Removing 100, currprime 2
Removing 102, currprime 2
Removing 104, currprime 2
Removing 106, currprime 2
Removing 108, currprime 2
Removing 110, currprime 2
Removing 112, currprime 2
Removing 114, currprime 2
Removing 116, currprime 2
Removing 118, currprime 2
Removing 120, currprime 2
3 is a Prime Number
Removing 9, currprime 3
Removing 15, currprime 3
Removing 21, currprime 3
Removing 27, currprime 3
Removing 33, currprime 3
Removing 39, currprime 3
Removing 45, currprime 3
Removing 51, currprime 3
Removing 57, currprime 3
Removing 63, currprime 3
Removing 69, currprime 3
Removing 75, currprime 3
Removing 81, currprime 3
Removing 87, currprime 3
Removing 93, currprime 3
Removing 99, currprime 3
Removing 105, currprime 3
Removing 111, currprime 3
Removing 117, currprime 3
5 is a Prime Number
Removing 25, currprime 5
Removing 35, currprime 5
Removing 55, currprime 5
Removing 65, currprime 5
Removing 85, currprime 5
Removing 95, currprime 5
Removing 115, currprime 5
7 is a Prime Number
Removing 49, currprime 7
Removing 77, currprime 7
Removing 91, currprime 7
Removing 119, currprime 7
11 is a Prime Number
13 is a Prime Number
17 is a Prime Number
19 is a Prime Number
23 is a Prime Number
29 is a Prime Number
31 is a Prime Number
37 is a Prime Number
41 is a Prime Number
43 is a Prime Number
47 is a Prime Number
53 is a Prime Number
59 is a Prime Number
61 is a Prime Number
67 is a Prime Number
71 is a Prime Number
73 is a Prime Number
79 is a Prime Number
83 is a Prime Number
89 is a Prime Number
97 is a Prime Number
101 is a Prime Number
103 is a Prime Number
107 is a Prime Number
109 is a Prime Number
113 is a Prime Number

Printiing the content if intList
===================================
2 is a prime number
3 is a prime number
5 is a prime number
7 is a prime number
11 is a prime number
13 is a prime number
17 is a prime number
19 is a prime number
23 is a prime number
29 is a prime number
31 is a prime number
37 is a prime number
41 is a prime number
43 is a prime number
47 is a prime number
53 is a prime number
59 is a prime number
61 is a prime number
67 is a prime number
71 is a prime number
73 is a prime number
79 is a prime number
83 is a prime number
89 is a prime number
97 is a prime number
101 is a prime number
103 is a prime number
107 is a prime number
109 is a prime number
113 is a prime number
Good Bye

15 comments:

  1. cALviN::കാല്‍‌വിന്‍ said...

    Its Fun!

  2. cALviN::കാല്‍‌വിന്‍ said...

    ArrayList നു പകരം List ഉപയോഗിക്കുന്നതാണ്‌ കൂടുതല്‍ നല്ലത്. എനിക്ക് യൂണിക്സില്‍ List കമ്പൈല്‍ ആവുന്നില്ല. അതിനാല്‍ ArrayList ഉപയോഗിച്ചു എന്ന് മാത്രം

  3. Umesh::ഉമേഷ് said...

    How did Eratosthenes become Euler?

    Looks like your program is unnecessary complex. Here is my 9-year old son did it in Python, after he read Eratosthenes' sieve in a book.

    max = 1000
    primes = []
    for x in range(0, max):
      primes.append('y')

    primes[0] = 'n'
    primes[1] = 'n'

    for number in range(0, max):
      if primes[number] == 'y':
        for i in range(2 * number, max, number):
          primes[i] = 'n'

    for x in range(0, max):
      if primes[x] == 'y':
        print x

  4. cALviN::കാല്‍‌വിന്‍ said...

    ഉമേഷേട്ടാ...
    ഫ്ലാഗ് ഉപയോഗിക്കാന്‍ പാടില്ല എന്ന കണ്ടീഷനുണ്ട്......

    ഇറാത്തോസ്തനീസില്‍ നിന്നും യൂളറിലേക്ക് മാറിയത് ബ്ലോഗില്‍ തന്നെ ഞാന്‍ പറഞ്ഞല്ലോ.
    യൂളറിന്റെ അല്‍ഗോരിതത്തില്‍ മുന്‍പ് റിമൂവ് ചെയ്‌ത സംഖ്യ വീണ്ടൂം റിമൂവ് ചെയ്യപ്പെടില്ല/ചെയ്യാന്‍ ശ്രമിക്കില്ല.

  5. cALviN::കാല്‍‌വിന്‍ said...

    Just to add...

    we can modify the while loop in public void FindPrime(int iMax)

    from
    while (currIndex < lastIndex)

    to
    while ((currIndex*currIndex) < iMax)


    the code will be extremely efficient then

  6. കുതിരവട്ടന്‍ :: kuthiravattan said...
    This comment has been removed by the author.
  7. സുബിന്‍ said...

    എന്നാ പിന്നെ ഞാന്‍ പേളില്‍ കൂടി എഴുതാം.. ഹ ഹ.. ഇതിനു പേള്‍ കൂടുതല്‍ ചേരും എന്ന് തോന്നുന്നു. ഏതായാലും കുറെ ലാംഗ്വേജസ് വന്നതല്ലേ.. ദാ ഇതും ഒന്ന് നോക്കിക്കോ..

  8. സുബിന്‍ said...

    ഇത് ഞാന്‍ എഴുതിയ കോഡ് അല്ല പക്ഷെ എക്സിക്യൂട്ട് ചെയ്യാന്‍ എടുക്കുന്ന സമയം വളരെ കുറവായി തോന്നി. ഈ കോഡ് ഇനിയും ചെറുതാക്കാനും കഴിയും..

    print "\n=======================\n";
    print "PRIME NUMBERS GENERATOR\n";
    print "=======================\n";
    # Get the range
    print "Minimum value of primes: ";
    my $min = ;
    chomp $min;
    print "Maximum value of primes: ";
    my $max = ;
    chomp $max;
    # Create a max-sized array
    my @primes = (1...$max);
    # Initially assume all numbers are prime
    for($i = 0; $i < $max; $i++) {
    $primes[$i] = 1;
    }
    # The sieve
    for ($i=2; $i*$i <= $max;$i+=1) {
    if ($primes[$i]) {
    for ($j=$i; $j*$i < $max; $j+=1) {
    $primes[$i * $j] = 0;
    }
    }
    }
    # Show the results
    my @p = ();
    for ($i=$min; $i<=$max; $i++) {
    if ($primes[$i]) {
    push @p, $i;
    }
    }
    $size = @p;
    print qq(Found $size primes:\n@p\n);

    ആരെങ്കിലും വേറെ ഏതെങ്കിലും ഭാഷയില്‍ എഴുതുകയാണെങ്കില്‍ ഇത് ഒരു കളക്ഷന്‍ ആക്കാമായിരുന്നു. ഇത് ഞാന്‍ ഈ മച്ചുനന്റെ അടുത്തുനിന്നും പോക്കിയതാ.. ഫ്രഷ്‌ ആയി എഴുതാന്‍ സമയമില്ല..

  9. സുബിന്‍ said...

    #!/usr/bin/perl -w
    use strict

    can be added at beginning for Linux. The LIST thing is inbuilt, efficient and really simple here. Just wanted to notify you.

  10. സുബിന്‍ said...

    =======================
    PRIME NUMBERS GENERATOR
    =======================
    Minimum value of primes: 1
    Maximum value of primes: 500
    Found 95 primes:
    2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103
    107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 211
    223 227 229 233 239 241 251 257 263 269 271 277 281 283 293 307 311 313 317 331
    337 347 349 353 359 367 373 379 383 389 397 401 409 419 421 431 433 439 443 449
    457 461 463 467 479 487 491 499

  11. Anoop said...

    "യൂളർ" അല്ല, "ഓയ്‌ലർ" എന്നാണു അദ്ദേഹത്തിന്റെ പേരിന്റെ ഉച്ചാരണം.

    കോഡിംഗ്‌ ഇത്രയും complicated ആക്കേണ്ട കാര്യമില്ല എന്നാണു എന്റെയും അഭിപ്രായം.

    ഇപ്പോൾ MATLAB ഉപയോഗിക്കുന്നതു കൊണ്ടു കോഡിംഗ്‌ ചെയ്യാറില്ല എന്നു തന്നെ പറയാം. എല്ലാത്തിനും inbuilt ഫങ്ങ്ഷൻസ്‌ ഉണ്ടല്ലോ. പണ്ടു പഠിച്ച കാര്യങ്ങൾ revise ചെയ്യാൻ ഈ പോസ്റ്റ്‌ സഹയകമായി.

  12. Melethil said...

    അളിയാ ഇതെടുത്തു ഇംഗ്ലീഷില്‍ ഇടാമോ?

  13. വഷളന്‍ (Vashalan) said...
    This comment has been removed by the author.
  14. വഷളന്‍ (Vashalan) said...

    The essence of OO programming is using high level abstractions instead of primitive types. I have written in Java using Set. Sieve is essentially a set...

    Not sure the program may compile... Haven't tested. But you got the idea...

    import java.util.*;
    public class Prime{
    private Set sieve =new TreeSet();
    private Set primes =new TreeSet();
    public Set getPrimes() {
    return primes;
    }
    Prime (int max){
    for (int i=2; i<=max; i++){
    sieve.add(new Integer(i));
    }

    while(!sieve.isEmpty())
    {
    Integer currentPrime = (Integer) seive.first();
    primes.add (currentPrime);
    sieve.remove(currentPrime);

    Iterator sieveIterator = sieve.iterator()
    while (sieveIterator.hasNext(){
    Integer currentNumber = (Integer) iterator.next();
    if (currentNumber.intValue() % currentPrime.intValue() == 0){
    sieve.remove(currentNumber);
    }
    }
    }
    }
    public static void main(String[] args) {
    Prime p = new Prime(1000);
    Iterator it = p.getPrimes().iterator();
    while(it.hasNext()){
    Integer primeValue = (Integer) it.next();
    System.out.println("Prime :"+ primeValue.toString());
    }
    }
    }

  15. sonu said...

    ഞാനും സി ഷാർപ്പിൽ ഒരു കുഞ്ഞു പ്രോഗ്രാം (600KB) എഴുതി. സമയമുണ്ടെങ്കിൽ പരീക്ഷിച്ചു നോക്കണേ.
    www.malayalamtyping.page.tl

Post Your Comment (പഴയ കമന്റ്‌ ഫോം?)

അഭിപ്രായങ്ങള്‍ക്ക് സുസ്വാഗതം.
തെറിവിളികള്‍, വ്യക്തിഹത്യ മുതലായവയെ ഒഴിവാക്കുമല്ലോ.
അനോണിമസ് ഓപ്ഷന്‍ തല്‍ക്കാലം ലഭ്യമല്ല. പഴയ പോസ്റ്റുകള്‍ക്ക് കമന്റ് മോഡറേഷന്‍ ഉണ്ട്. സരസമായ ഓഫുകളെ നിരുത്സാഹപ്പെടുത്തുന്നില്ല. മനപൂര്‍‌വം വിഷയത്തില്‍ നിന്നും വഴി തിരിച്ചു വിടുന്ന കമന്റുകള്‍ ഡിലീറ്റ് ചെയ്യപ്പെട്ടേക്കാം.

CopyLeft Information

Singularity എന്ന ബ്ലോഗില്‍ പ്രസിദ്ധീകരിക്കുന്ന ലേഖനങ്ങള്‍ എല്ലാം പൊതുതാല്പര്യാര്‍ത്ഥം ഉള്ളതാണ്. അവ ലേഖകന്റെ അനുമതി കൂടാതെ തന്നെ വാണിജ്യപരമോ വാണിജ്യേതരമോ ആയ എന്താവശ്യത്തിനും ഏതൊരാള്‍ക്കും എപ്പോഴും എത്ര തവണ വേണമെങ്കിലും മാറ്റങ്ങളോടെയോ അതേ പടിയോ ബ്ലോഗിലോ ഇതരമാധ്യമങ്ങളിലോ സ്വതന്ത്രവും സൌജന്യവുമായി ഉപയോഗിക്കാം. മാറ്റം വരുത്തുന്ന പക്ഷം അതില്‍ ഈ ലേഖകന്‍‍ ഉത്തരവാദിയല്ല. പുനഃപ്രസിദ്ധീകരിക്കുന്ന കുറിപ്പിനൊപ്പം മൂലലേഖനത്തിന്റെ രചയിതാവു് എന്ന സ്ഥാനം ലേഖകനു് നല്‍കുന്നതു് അഭികാമ്യം. എന്നാല്‍ ഇതു് നിബന്ധനയല്ല. മറ്റൊരാളുടെ പേരു് പകരം കൊടുക്കാന്‍ അനുമതിയില്ല. വീണ്ടും ഉപയോഗിക്കുന്ന പക്ഷം ആ വിവരം ലേഖകനെ അറിയിക്കണമെന്നും ഈ പകര്‍പ്പുപേക്ഷാപത്രം ഒപ്പം നല്‍കണമെന്നും താത്പര്യപ്പെടുന്നു.