angryziber / kotlin-puzzlers

A collection of Kotlin Puzzlers
419 stars 58 forks source link

Puzzler idea related to ranges and steps #57

Closed SerVB closed 4 years ago

SerVB commented 5 years ago

Hi! Don't know English very well so create an issue instead of a PR. Hope you will adopt this description.

Puzzler idea:

for (i in 1..10 step 2 step 3) {
    println(i)
}

What will happen?

Correct answer:

Click here to view the spoiler Something else: it will print 1 4 7.

Why?

Because (1) step overwrites the previous step and constructs a new object (Kotlin sources):

public infix fun IntProgression.step(step: Int): IntProgression {
    checkStepIsPositive(step > 0, step)
    return IntProgression.fromClosedRange(first, last, if (this.step > 0) step else -step)
}

And (2) in the new object the last element is recalculated (Kotlin sources):

internal fun getProgressionLastElement(start: Int, end: Int, step: Int): Int = when {
    step > 0 -> if (start >= end) end else end - differenceModulo(end, start, step)
    step < 0 -> if (start <= end) end else end + differenceModulo(start, end, -step)
    else -> throw kotlin.IllegalArgumentException("Step is zero.")
}

So 1..10 step 2 becomes 1..9 step 2because of (2).
Then 1..9 step 2 step 3 becomes 1..9 step 3 because of (1)
and finally becomes 1..7 step 3 because of (2) again.