2
val primes = generateSequence(2 to generateSequence(3) {it + 2}) {
  val currSeq = it.second.iterator()
  val nextPrime = currSeq.next()
  nextPrime to currSeq.asSequence().filter { it % nextPrime != 0}
}.map {it.first}
println(primes.take(10).toList()) // prints [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

I tried to understand this function about how it works, but not easy to me. Could someone explain how it works? Thanks.

Will Ness
  • 70,110
  • 9
  • 98
  • 181
Zynastor
  • 71
  • 8
  • Welcome on stackoverflow. Please do not ask generally to explain a block of code, because it is probably of little value to others. See here: https://meta.stackexchange.com/a/188082/310893 General advice: Checkout https://play.kotlinlang.org/, first understand what generateSequence does and try to decompose the function you don't understand as much as possible – Fabian Braun Nov 11 '20 at 22:14

1 Answers1

4

It generates an infinite sequence of primes using the "Sieve of Eratosthenes" (see here: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes).

This implementation uses a sequence of pairs to do this. The first element of every pair is the current prime, and the second element is a sequence of integers larger than that prime which is not divisible by any previous prime.

It starts with the pair 2 to [3, 5, 7, 9, 11, 13, 15, 17, ...], which is given by 2 to generateSequence(3) { it + 2 }. Using this pair, we create the next pair of the sequence by taking the first element of the sequence (which is now 3), and then removing all numbers divisible by 3 from the sequence (removing 9, 15, 21 and so on). This gives us this pair: 3 to [5, 7, 11, 13, 17, ...]. Repeating this pattern will give us all primes.

After creating a sequence of pairs like this, we are finally doing .map { it.first } to pick only the actual primes, and not the inner sequences.

The sequence of pairs will evolve like this:

2 to [3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, ...]
3 to [5, 7, 11, 13, 17, 19, 23, 25, 29, ...]
5 to [7, 11, 13, 17, 19, 23, 29, ...]
7 to [11, 13, 17, 19, 23, 29, ...]
11 to [13, 17, 19, 23, 29, ...]
13 to [17, 19, 23, 29, ...]
// and so on
marstran
  • 26,413
  • 5
  • 61
  • 67
  • Great explanation! And hopefully the OP doesn't feel too bad about not being able to puzzle it out, it's clever but not exactly easy to follow if you're not used to functional programming (IMO anyway) – cactustictacs Nov 12 '20 at 02:19
  • Thank you very much. Now I understood how generateSequences works exactly! – Zynastor Nov 12 '20 at 04:31
  • not of Eratosthenes though, but [of Turner](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#cite_ref-12) (or Quarendon, but Turner's turned out to be much more famous) – Will Ness Nov 14 '20 at 22:09