Skip to content

Les Nombres premiers

Objectifs didactiques

  • Utilisation d'un tableau (array)
  • Consideration d'optimisation

Entrée Wikipedia pour Ératosthène

Disciple d'Ariston de Chios, Ératosthène fut nommé à la tête de la bibliothèque d'Alexandrie vers -245 à la demande de Ptolémée III, pharaon d'Égypte, et fut précepteur de son fils Ptolémée IV. Selon Suidas, il se laissa mourir de faim, parce que, devenu aveugle, il ne pouvait plus admirer les étoiles.

En tant que mathématicien, il établit le crible d'Ératosthène, méthode qui permet de déterminer par exclusion tous les nombres premiers.

Le crible d'Ératosthène

fun printPrimes(n: Int) {
    val isPrimeArray: Array<Boolean> = Array(n, { true })
    isPrimeArray[0] = false
    isPrimeArray[1] = false
    for (i: Int in 2 until n) {
        for (j: Int in i*2 until n step i) { // j=i*2,i*3, i*4, ...
            isPrimeArray[j] = false
        }
    }

    // loop through array and print primes
    for (i: Int in 2 until n)
        if (isPrimeArray[i])
            println(i)

}

fun main(args: Array<String>) {
    printPrimes(100))
}
[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]

Quelques optimisations

Première optimisation pour reduire le nombre d'itérations

Code
fun primes(n: Int) {
    val isPrimeArray: Array<Boolean> = Array(n, { true })
    isPrimeArray[0] = false
    isPrimeArray[1] = false
    for (i: Int in 2 until n) {
        if (isPrimeArray[i]) { // inner loop only if i is prime
            println(i) // directly print i since it is prime
            for (j: Int in i * 2 until n step i) {
                isPrimeArray[j] = false
            }
        }   
    }
}

Et encore: on s'arrête à \sqrt{n}

Code
fun primes(n: Int) {
    val isPrimeArray: Array<Boolean> = Array(n, { true })
    isPrimeArray[0] = false
    isPrimeArray[1] = false
    for (i: Int in 2 until Math.sqrt(n.toDouble()).toInt()) {
        if (isPrimeArray[i]) { 
            println(i)
            for (j: Int in i * 2 until n step i) {
                isPrimeArray[j] = false
            }
        }   
    }
}

Variante

Construction itérative de la solution:

Code
fun primes(n: Int): List<Int> {
    val sieve: Array<Boolean> = Array(n, { true })
    val result: ArrayList<Int> = ArrayList()
    sieve[0] = false
    sieve[1] = false
    for (i: Int in 2 until n) {
        if (sieve[i]) {
            result.add(i)
            for (j: Int in i * 2 until n step i) {
                sieve[j] = false
            }
        }   
    }
    return result
}